Title: Introduction to Refactoring
1Introduction to Refactoring
- Jim Cooper
- Falafel Software
2Refactoring
- Refactoring. Improving the Design of Existing
Code - Martin Fowler
- 2000, Addison-Wesley
- ISBN 0-201-48567-2
- We will use that terminology, guidelines and
naming
3What is Refactoring?
- Refactoring is the process of changing a
software system in such a way that it does not
alter the external behaviour of the code yet
improves its internal structure. - Term applies both to the process and the
individual techniques
4What is Refactoring? - 2
- Each refactoring is a series of steps
- Each step is simple and small
- Minimises introduction of new bugs
- Unit tests used to verify changes
- Behavioural changes to a program are not
refactorings
5Why Refactor?
- Code is not for computers to read, its for us to
read - 90 of the lifetime of most software is in
maintenance mode - Source code must be easy for humans to read,
understand and modify - Refactoring helps make the code more usable by
programmers
6Aims of Refactoring
- Improved design
- Make code easier to understand
- Can use it on other peoples code
- Help find bugs
- Faster programming in the long term
- Formalise and name best practices
- Easier to talk about
- Reduce chaos in long-lived code
7Opportunities for Refactoring
- When adding functionality
- Make adding new feature easier
- Keep refactoring separate, though
- When fixing a bug
- During a code review
- Pair programming
- Refactoring takes time
- Sneak it past managers ?
8Refactoring Techniques
- Too many to look at all of them
- Will not discuss unit testing in detail
- Start with the main ones, and then browse the
book looking at others - No need to read the book cover to cover (its not
that interesting)
9Points to Note
- Refactoring relies heavily on having object
oriented code - Refactorings are usually more atomic than
patterns, but some use patterns - Often language dependent
- Refactoring book is very Java oriented
- We will cover converting to Delphi
- Not many refactorings use interfaces
10Points to Note - 2
- Many refactorings make use of other, simpler
refactorings - Some are opposites
- Use the one that makes your code easier to
understand - Can apply some mechanically
- It is possible to go too far!
11Extract Method
- Probably the most used technique
- You should have done this many times yourself
- Identify code to reuse, or that is making a
method too long, so we make a new method out of
it - Difference here is the formal definition of the
process, and the guidelines for its use
12Structure of Extract Method
- Name Extract Method
- Summary describes when to use
- You have a code fragment that can be grouped
together - Turn the fragment into a method whose name
explains the purpose of the method
13Structure of Extract Method - 2
- Short code example
- Motivation
- Describes why the refactoring should be done, and
also when it shouldnt - Mechanics
- Step by step instructions
- One or more longer examples, usually with
discussion
14Structure of Extract Method - 3
- Motivation
- A method is too long
- A section of code needs a comment to explain it
- Short (well-named) methods easier to reuse and
override - Higher-level methods easier to read
- Good naming is key
15Structure of Extract Method - 4
- Mechanics
- Create a new method with a good name
- Copy extracted code to new method
- Deal with variables and parameters in the
original method
16Dealing with Variables
- Local variables only used in the extracted code
can be copied to the new method - One original variable modified
- Make the new method a function
- Several original variables modified
- Use var parameters
- Use other refactorings first
17Dealing with Variables - 2
- Replace Temp with Query
- Remove local variable, move expression to a
method and call it each time the variable was
used - Split Temporary Variable
- Use a different local variable for each assignment
18Structure of Extract Method - 5
- Pass any original parameters used to the new
method - Compile
- Replace extracted code with method call
- Remove any local variables no longer used
- Compile and test
- Dont forget to test!!
19Extract Class
- Used when a class is violating the principle of
separation of concerns - Often the result of feature creep
- Can result from too many Extract Method
refactorings - Splits out related subset of data and methods
into a new class - May need to rename the old class if its duties
have changed
20Extract Class - 2
- Normally need a reference to an object of the new
class in the old one - Leave the new class in the implementation section
if only used internally - Uses Move Field and Move Method refactorings to
move elements of the new class across (test after
each move)
21Inline Class
- The opposite of Extract Class
- Applied when a class is doing too little
- Move fields and methods into a class that uses
them (there wont be many) - Fowler humour
- The last step of the refactoring reads Hold a
short, simple funeral service
22Move Method
- Moves a method from one class to another
- May change name in the new class
- Original class probably needs to refer to an
instance of the new one - If the method is declared in an ancestor or
descendant class, may not be able to move it
easily
23Inline Temp
- Replace a local variable assigned to with a
simple expression, with the expression - Removing local variables can make other
refactorings easier - Local variable may be doing no harm, or may be
there to avoid breaking the Law of Demeter - Leave it there
24Rename Method
- If the task of a method has changed, rename it to
reflect the new duties - Seems trivial, but is very important
- Bad naming defeats the whole purpose of
encapsulation - Code is confusing, in the worst case it can be
completely misinterpreted
25Replace Magic Number with Symbolic Constant
- Encapsulates a standard piece of programming
advice - Applies to strings etc, as well, of course
- This sort of refactoring useful when training new
programmers
26Replace Error Code with Exception
- If you dont already do this, line up at the
front for a slapping ? - Code can be written assuming it works, and is
therefore much easier to read - Error handling code separated out
27Encapsulate Field
- Needs to be modified for Delphi
- Replace Field with Property
- Replace a public field with a property
- Otherwise the Delphi Style Police will come and
kick you around - Use the Delphi naming convention
- Move field to private, rename with F
- Make a property named without the F
28Self Encapsulate Field
- We might allow direct access to a field within a
class, if field is private - If field needs to be protected or better, or has
side effects when used, then make it into a
property - Direct access in constructor, destructor and
property accessor methods - Use Replace Field with Property
29Remove Control Flag
- Some people use a local variable as a control
flag to break out of loops - Ive even seen goto used this way!
- Use Break, Continue and Exit instead
30Replace Type Code with State/Strategy
- This refactoring introduces either the State or
Strategy pattern - Used when the class behaviour varies depending on
some state value - Lots of case statements are a giveaway
- Demo code
31Finite State Machine
- This example is from ToD, with the kind
permission of Julian Bucknall
32Convert Refactorings to Delphi
- Use const instead of final
- To make an immutable class, make all the
properties read only, and set their values in the
constructor - Query Function
- Temporary variable local variable
- Some refactorings cannot be applied
- e.g. garbage collection
33When to Refactor Bad Smells
- Kent Becks idea
- Combination of experience and intuition sometimes
makes us feel code just isnt right - There are some indicators we can look for
- Bad Smells
- Have names and recommended treatments
34Bad Smells
- Duplicated Code
- Long Method
- Large Class
- Long Parameter List
- Divergent Change
- Shotgun Surgery
- Feature Envy
35Bad Smells - 2
- Data Clumps
- Primitive Obsession
- Switch Statements
- Parallel Inheritance Hierachies
- Lazy Class
- Speculative Generality
- Data Class, Refused Bequest
- Comments
36Problems
- Do not apply refactorings without thought for the
consequences - Threads
- Discipline is new, so not all problems found yet
- Databases
- Changing interfaces
- Designs difficult to refactor
- Code is beyond all help
37Miscellaneous
- Still need upfront design, but can design for
ease of refactoring - Dont make design too flexible
- Dont make optimisation decisions before finding
bottlenecks - Refactor first, optimise after
- Tools exist for Java (some in JBuilder) and C,
but little for Delphi ...
38Refactoring in Delphi
- Until now!
- Diamondback has the following refactorings built
in, with a promise of many more to follow - Rename
- Extract Method
- Extract Resource String
39Refactoring in Delphi - 2
- In addition, the new refactoring engine makes
possible some handy things which are not,
strictly speaking, refactorings - SyncEdit mode
- Find References
- Declare Variable
- Declare Field
- Import Namespace
40Questions?
41Thank You
- You can contact me further atjim_at_falafelsoft.com