Title: Introduction To Refactorings
1Introduction To Refactorings The Lecture by
Alexander Binun
2 What is Refactoring? A Refactoring
is an automatic change of the internal structure
of a program performed in order to improve some
important (from the developer viewpoint)
characteristics (readability, understandability,
etc.) while preserving the program behavior.
3 History The Refactoring paradigm was first
suggested by William Opdyke (1992) as a set of
lowest-level operations intended to change the OO
schema structure (Create Empty Class, Add
Variable) and rules to build more complex
refactorings. Tokuda and Batory (1995)
investigate building Design Patterns from
elementary Refactorings. Don Roberts (1999)
builds a rigorous framework (including formal
notions of program behavior, using First-Order
Logic to specify domain and range of a
refactoring, and so on). Martin Fowler (1999)
presented the intuitive approach to Refactorings
(from the viewpoint of software engineer), that
was accepted in industry.
4 Sources and
References This lecture was built using lecture
slides of William Opdyke and Frank Tip. Also
there were used 1. M. Fowler
Refactoring Improving the Design of Existing
Programs. Addison-Wesley. 1999. 2. W.
Opdyke. Refactoring Object-Oriented Frameworks.
PhD thesis, University of Illinois at
Urbana-Champaign, Dept. of Computer
Science, 1992. 3. Don Roberts. Practical
Analysis for Refactoring. PhD thesis,
University of Illinois at Urbana Champaign, 1999.
And even more www.refactoring.com/sources.html.
..
5Refactoring Presentation Outline 1. Motivation
Example 2. Refactoring Solution Definition
Why Behavior Preserving A Category of
Refactorings Some Sample Refactorings Some
Refactoring Features 3. Evolution with
Refactorings 4. Refactoring tools 5. Refactoring
real applications 6. Refactoring Limitations 7.
Summary
- Contents
-
- Motivation (example)
- 2. Program restructuring.
- 3. Refactoring Details
- a) Definition
- b) Behavior Preserving
- c) When to Apply
- d) Move Method An Example Refactoring
- e) Categorization of Refactorings (Fowler)
- f) Categorization of Refactorings (Opdyke)
- g) Refactoring to Design Patterns
(Tokuda,Batory) -
- 4. Refactoring Tools
- 5. Refactoring Limitations
- 6. Open Issues
6double chargeFor(date start,date end) return
((end start)10)
Motivation Consider evolution of a small
program
Customer
lastBillDateDate
addBill (dateDate, amountdouble) createBill
(dDate) chargeFor (startDate, endDate)
double chargeFor(date start,date end)
return ((end start)10) New requirement A
Customer can be either Member Or Guest with
different policies for chargeFor.
7 Solution 1 Manual Case creation double
chargeFor(date start,date end) Case
GUEST return ((end start)10)
Case MEMBER return ((end
start)5)
8- Manual Program Restructuring
- Create separate classes for guestCustomer and
memberCustomer without hierarchy. - Subclass guestCustomer and memberCustomer from
Customer, overriding chargeFor. - So we should do the following
- 1. Fix bugs
- 2. Add new functions.
- 3. Perform preventive maintenance of the new
- version
- Then we encounter the following problems
- Time Consuming, Difficult and Error Prone.
9Refactoring Presentation Outline 1. Motivation
Example 2. Refactoring Solution Definition
Why Behavior Preserving A Category of
Refactorings Some Sample Refactorings Some
Refactoring Features 3. Evolution with
Refactorings 4. Refactoring tools 5. Refactoring
real applications 6. Refactoring Limitations 7.
Summary
- Where We Are
-
- Motivation (example)
- 2. Program restructuring.
- 3. Refactoring Details
- a) Definition
-
10 Refactoring -
Definition A Refactoring is a change made to the
internal structure of a software component to
make it easier to understand and cheaper to
modify, without changing the observable behavior
of that software component. For OO schemas
this means redistributing attributes (methods)
across an OO schema in order to achieve clearer
understanding, etc. without changing the object
behavior (i.e. to return the same result on ALL
possible inputs after a refactoring). Method
bodies often should be examined in order to
preserve consistency with the performed changes
(if a variable is renamed, all references to it
should be updated)
11- The following questions arise immediately
- When should we refactor ? In other words, which
code should be considered to be bad so that a
particular refactoring must be applied? - What is behavior preserving ? We cannot test
the original and the refactored program on ALL
possible inputs (maybe infinite number of
inputs). - 3) What is to make a program more
understandable ? Can we devise more rigorous
purpose functions to measure
understandability or some other feature being
improved? - ...
-
12 When to Refactor Bad
Smells Bad smelling code is a code with
drawbacks that should be repaired by a concrete
refactoring. 1) Duplicated code (the same
code structure in more than one place)
perform Extract Method 2) Large Class (a
class is trying to do too much)
divide it into several classes Extract
Subclass. (remember High Cohesion OOAD
course) 3) Long switch-case chains include
each branch into a separate subclass
and use polymorphism Replace
Conditional With Polymorphism These rules are
heuristical ones! Rigorous rules when to refactor
have yet to be designed!!!
13- What is Behavior preserving ?
- Returning the same result before and after
applying a refactoring. - How can we ensure this?
- 1) For each concrete case, give a mathematical
proof that the original and the refactored
program are equivalent. - Its undecidable in the general case its
hard to prove it manually for each concrete case
tools of Program Analysis are not sufficiently
developed. - Designing of tests or other behavior
approximations class invariants (an expression
written in some language that remains TRUE at
each program state. - No guarantees, cannot cover all cases
cannot be done in general. - But in particular cases produces quick
and satisfactory estimate!! - Program analysis.
- Difficult to implement analysis may be
imprecise and slow. - But this technique is sufficiently
generic!!
14Refactoring Presentation Outline 1. Motivation
Example 2. Refactoring Solution Definition
Why Behavior Preserving A Category of
Refactorings Some Sample Refactorings Some
Refactoring Features 3. Evolution with
Refactorings 4. Refactoring tools 5. Refactoring
real applications 6. Refactoring Limitations 7.
Summary
- Where We Are
-
- Motivation (example)
- 2. Program restructuring.
- 3. Refactoring Details
- a) Definition
- b) Behavior Preserving
- c) Bad Smells - When to Apply
- d) Move Method An Example Refactoring
-
15 Move Method An Example
Refactoring Problem A method is using or is
used by more features of another class than the
class on which it is defined (remember Low
Coupling OOAD) Approach create a new method
with a similar body in the class it uses most, or
either turn the old method into a simple
delegation, or remove it altogether (if nobody
uses this method in the original class!!).
16- Move Method The
Main Stages -
- Examine features used by the source method that
are defined on the source class. Consider whether
they should be moved as well. - Check for overriding definitions in sub(super)
classes. In general, cannot move if there is
polymorphism (in order not to affect the
hierarchy!) - Declare method in the target class (the code is
copied from the source class and the references
to source are adjusted). - Determine how to access the target object from
the source. - Turn source method into delegator to the target
(removal is also possible).
17public class Account double overdraftCharge() i
f (_type.isPremium()) double result 10 if
(_daysOverdrawn gt 7) result (_daysOverdrawn -
7)0.85 return result else return
_daysOverdrawn1.75 double bankCharge() double
result 4.5 if (_daysOverdrawn gt 0) result
overdraftCharge() return result private
AccountType _type private int _daysOverdrawn M
ove Method Example
1. Examining features used by the source method
in the source class
18 Some observations and results
19(No Transcript)
20 And the result is
21(No Transcript)
22Refactoring Presentation Outline 1. Motivation
Example 2. Refactoring Solution Definition
Why Behavior Preserving A Category of
Refactorings Some Sample Refactorings Some
Refactoring Features 3. Evolution with
Refactorings 4. Refactoring tools 5. Refactoring
real applications 6. Refactoring Limitations 7.
Summary
- Where We Are
-
- Motivation (example)
- 2. Program restructuring.
- 3. Refactoring Details
- a) Definition
- b) Behavior Preserving
- c) When to Apply
- d) Move Method An Example Refactoring
- e) Categorization of Refactorings (Fowler)
-
23 Categorization of Refactorings
(Fowler) Composing of Methods 1)
Extract Method/Inline Method extracting a
clump of code into a separate method (or
putting the method body into the caller
body). 2) Split Temporary Var/Inline
Temporary Var putting the result of
an expression into a temporary
variable (or inserting an expression
instead of temp var containing it). 3) Remove
assignments to parameter replacing
of local parameters with temporary variables to
avoid parameter modifications
24 Categorization of Refactorings (cont.)
Composing of Methods 4) Replace Method with
Method Object - a long method that intensively
uses local variables so that Extract Method
cannot be applied can be converted into its own
object so that all the local variables become
fields on that object. 5) Substitute
Algorithms replacing a long algorithm with the
new (and more readable) one.
25 An Example for Composing
Methods Split Temporary
Variable Before double temp 2 (_height
_width) System.out.println (temp) temp
_height _width System.out.println (temp)
After final double perimeter 2 (_height
_width) System.out.println (perimeter) final
double area _height _width
System.out.println (area)
26 Categorization of
Refactorings (cont) - Moving
Features Between Classes 1) Move Method
(Move Field) moving methods or fields
across a hierarchy. The following problems have
to be solved how to create target
field (method) how to reference the
newly created target from the source how to
update references to the feature being
replaced in the source class and so
on. 2) Extract Class if a class is doing
too much work, create a new class,
move some fields (methods) into a new class
and link the source and the target
classes. Inline Class doing the
opposite work. 3) Make Delegate (Remove
Delegate) deleting delegate calls
(classes) that do not perform any essential job
(except for delegeting calls). A
delegation chain is pruned.
27- Categorization of Refactorings - Data Organizing
- These refactorings allow to reorganize data
within a single class. Due to large number of
refactorings, only main refactorings will be
reviewed briefly. - Encapsulate Field - Create getting and setting
methods for the field and use only those to
access the field. - Change the data item into object - if the data
item needs additional data or behavior, turn it
into an object. - Update Associations convert unidirectional
associations into bidirectional (and vice versa),
by updating pointers in linked classes. - Replace constant values with literal constants
(final - Java). - Replace Subclass with fields if there are
subclasses that vary only in methods that return
constant data, change the methods to superclass
fields and eliminate the subclasses.
28 An Example for Data
Organizing
Self-Encapsulate Field Before private int
_low, _high boolean includes (int arg)
return arg gt _low arg lt _high
Afterprivate int _low, _high boolean
includes (int arg) return arg gt getLow()
arg lt getHigh() int getLow() return
_low int getHigh() return _high
29- Simplifying Conditional Expression
- Decompose Conditional if the condition (then
else) parts are complicated, form separate
methods for the complicated parts and replace
them. - Consolidate Conditional Expression if there is
a long sequence of conditional tests with the
same result, combine tests into a single
conditional expression and extract it. - Consolidate Duplicate Conditional if the same
fragment of code is in all branches of a
conditional expression, move it outside of the
expression. - Remove Control Flag if there is a variable
that is acting as a control flag for a series of
boolean expressions, use a break or return
instead. - Introduce Assertion if a section of code
assumes something about the program state, make
this assumption explicit with an assertion. - And so on
-
30 An Example for Simplifying
Conditional Expressions - Decompose
Conditional Before if (date.before
(SUMMER_START) date.after(SUMMER_END))
charge quantity _winterRate
_winterServiceCharge else charge
quantity _summerRate After if
(notSummer(date)) charge
winterCharge(quantity) else charge
summerCharge (quantity)
31- Making Method Calls
Simpler - Rename Method if the method name does not
reveal its purpose, change its name and update
calls to this method). - Add/Remove Parameter if a method needs more
information about the caller (or does not need
some information), parameters may be added or
deleted. - Parameterize Method/Replace Parameter with
Separate Method if several methods do similar
things but with different values contained in the
method body (or, vice versa, a method runs
different code depending on the values of an
enumerated parameter), create one method that
uses a parameter for the different values (or
create a separate method for each value of the
parameter). - Preserve Whole Object - if you are getting
several values from an object and passing these
values as parameters in a method call, send the
whole object instead.
32 An Example for Making Method
Calls Simpler Rename Method If the name of
a method does not reveal its purpose (a class
Customer has a method Getinvcdlmt to compute
invoicable credit limit, then it is worth to
rename this method to getInvoicableCreditLimit
(updating all calls of this method).
33- Refactoring for Generalization
- Pull Up Field/Method if two subclasses have the
same field (or the method with identical results
on subclasses), then move this field (method) to
the superclass. Similarly, a field (method) may
be pushed down if it is relevant only for a
subclass. - Extract Subclass/Interface if there are
subclasses with similar features, a they may be
unified into a separate superclass (common
methods are extracted into an interface). - Collapse Hierarchy a subclass and a superclass
can be merged if they are not very different. - Replace Inheritance with Delegation (or vice
versa) if a subclass uses only part of a
superclasses interface, then create a field for
the superclass, adjust methods to delegate to the
superclass, and remove the subclassing - enforce
delegation). Conversely, if you're writing many
delegations for the interface, subclass the
delegating class from the delegate.
34An Example (from M.Fowler) Pull up a method
35Refactoring Presentation Outline 1. Motivation
Example 2. Refactoring Solution Definition
Why Behavior Preserving A Category of
Refactorings Some Sample Refactorings Some
Refactoring Features 3. Evolution with
Refactorings 4. Refactoring tools 5. Refactoring
real applications 6. Refactoring Limitations 7.
Summary
- Where We Are
-
- Motivation (example)
- 2. Program restructuring.
- 3. Refactoring Details
- a) Definition
- b) Behavior Preserving
- c) When to Apply
- d) Move Method An Example Refactoring
- e) Categorization of Refactorings (Fowler)
- f) Categorization of Refactorings (Opdyke)
-
36 Refactoring Classification William Opdyke
(1992) William Opdyke (1992) was the first who
explored the notion refactoring on OO
schemas. The main points 1) There are 26
lowest-level refactorings
(CreateClass, CreateVariable, etc.) that may be
combined to form more complex ones. 2)
The program behavior is approximated by a
program invariant a FOL formula on a given
OO schema 3) A refactoring can be
executed only after its precondition
(also a formula on a give OO schema) is
satisfied. Don Roberts has added the
postcondition notion
37 Opdykes low-level refactorings - Example
38 Opdykes examples Adding new function
39Opdykes primitive refactorings Move
attribute to superclass (analogous to Fowlers
Pull Up Field/Method )
40Opdykes primitive refactorings (Move Class)
combines related classes into an hierarchy
(classes A, B are related if according to
functionality, A may be viewed as a subcase of B)
41 Comparative characteristics of
Fowlers and Opdykes approaches Fowler
Reflects real-world situations (move method,
delegate), more intuitive and natural approach.
But! the lack of rigorous formulations and
language-dependency leads to inability to reuse
them as building bricks into more complex (and
language-independent) projects correctness
should be first proved. Opdyke The approach
is less intuitive (at first glance, powerless
primitive refactorings) , but it can be
elaborated into a rigorous language-independent
framework supporting.
42Refactoring Presentation Outline 1. Motivation
Example 2. Refactoring Solution Definition
Why Behavior Preserving A Category of
Refactorings Some Sample Refactorings Some
Refactoring Features 3. Evolution with
Refactorings 4. Refactoring tools 5. Refactoring
real applications 6. Refactoring Limitations 7.
Summary
- Where We Are
-
- Motivation (example)
- 2. Program restructuring.
- 3. Refactoring Details
- a) Definition
- b) Behavior Preserving
- c) When to Apply
- d) Move Method An Example Refactoring
- e) Categorization of Refactorings (Fowler)
- f) Categorization of Refactorings (Opdyke)
- g) Refactoring to Design Patterns
(Tokuda,Batory) -
-
43Tokuda, Batory (1995) combine refactorings into
design patterns. Example Bridge.
44(No Transcript)
45(No Transcript)
46(No Transcript)
475. create_member_function 6. substitute
48-
Refactoring Tools - Refactoring Browser http//www.refactory.com/Refac
toringBrowser/Refactorings.html - Stateless refactorings (perform a selected
refactoring), an attempt to build a
language-independent tool (front-ends for Java
and Smalltalk). - 2. Eclipse
- www.eclipse.org
- An open source platform for IDE development -
in many ways Eclipse is the Emacs for the 21st
century. It ships with a built in Java IDE that
includes a strong refactoring capability. - 3. C Refactory
- http//www.xtreme-simplicity.net/CSharpRefacto
ry.html - Built into MS Visual Studio. Supports C,
C, Java, Basic. Not only performs refactorings
selected by a user, but also assists a user in
this selecting (it helps to find areas that needs
attention by calculating metrics at the solution,
project, folder, file or type levels, etc.). -
49- Some Refactoring Limitations
- Validation How do we know a refactored program
is correct? - 2) Conservative Enabling Conditions (i.e. more
restrictive than necessary to perform a required
refactoring) reduction in conservation leads to
more powerful refactorings and complicates design
of refactoring tools. - 3) Program Families many files may be included
in a program (and shared by different programs).
Modern tools perform refactoring in a given file,
but powerful refactorings may affect many files a
program is resided in. - 4) Granularity large grain refactorings are
more convenient in practice, but primitive
refactorings are more convenient for composing
(if we need this feature).
50 Future Work -
Practical Area 1) Visualization of the
refactoring process how to expose
the various parts of a refactoring framework
(especially combination) to users?
2) Evolution refactorings as software evolves,
there will be code that must be updated
to the new design. The possible
solution is to sell the old version together with
a refactoring tool that will make the
new version from the old one rather
than to sell upgrades. 3) Multi-user
refactorings how to deal with conflicts
between groups of refactorings that may run in
parallel? How to preserve the program
integrity? A user may be granted
specific permissions indicating the refactorings
he(she) is allowed to perform (a
research in Security area).
51- Future Work Theoretical
Area - Presenting refactoring as functions (the domain,
the range, - their properties, does an inverse exists,
whether given refactorings are commutative, etc.) - 2) What is behavior preservation ? We cannot
test the original and the refactored programs on
ALL possible inputs, so approximations (class
invariants, etc.) have been invented. The
research should involve more complex and rigorous
probabilistic analysis of this issue.