Transcript Introduction to Java. Part II: Selected Libraries
Advanced Object-Oriented Design Lecture 5
Software Refactoring
Part I: Introduction Bartosz Walter
Motto „Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
Martin Fowler
Agenda 1. Refactoring: ideas, motivation, examples 2. Verification of refactorings 3. Bad smells in code
More functionality!
Oh, I've found a bug...
We've got no time. Let's integrate...
Motivation for refactoring High cost of maintenance Yourdon: 80% of TCD Software decays during development Low understanding of code Design does not fit the requirements/ functionality YAGNI =
Y
ou
A
ren't
G
oing to
N
eed
I
t
Refactoring Refactoring is: a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behaviour void doSth() void doSth()
Source: W. Opdyke
Simplest example Extract Method
void compAndPrint() { // compute X // compute Y ...
// print X // print Y ...
// store X // store Y }
One method – one function Allows localizing the potential bugs
void compute () // compute X // compute Y print(X, Y); // store X // store Y } { void print(X,Y) // print X // print Y } {
Simplest example (reverted) Inline Method
void compute () X = next(X); Y = next(Y); } { void compAndPrint() { ...
X++; Y++; ...
} int next(N) { return N++; }
Removal of very short methods
Cost of refactoring
Refactoring is costly because it does not add new functions to the system.
The cost depends on:
the language used support from CASE tools the type of refactorings number and quality of test cases
Important factors:
cost of documentation update cost of test cases update
When
to do
and not do refactoring?
Three strikes and refactor When adding new functions When fixing a bug While inspecting code
At close deadlines Prematurely published interfaces Unstable, rubbish code
Unfinished refactoring is like going into debt. You can live with it, but it is costly.
Ward Cunningham
Verification of refactorings
SIMPLE
Automated verification Implemented in many IDEs HARD
Verification requires testing Tests need to be manually created
Simple refactorings...
Verification of pre-conditions Static analysis of code
void doSth() If before....
If before....
void doSth() Then after....
Then after....
... and hard ones
Static code analysis, preconditions Role of unit tests
void doSth() void doSth() If before....
If before....
Then after....
Then after....
Bad smells If it stinks, change it
Kent Beck grandma discussing child-rearing philosophy
Duplicated Code
Same or similar code appears all over the system
in same class: extract out the common bits into their own method (extract method) in sibling classes: extract method with a shared functionality and then pull up the method to a common superclass in unrelated classes: extract class
Long Method
Same or similar code appears all over the system
Too many options, causing the method to do too many things Not enough support from other methods, causing the method to do tasks at a lower level than it should Overly complicated exception handling the rule of one screen/twenty lines extract code
Large class
Same or similar code appears all over the system
No clear definition of what the class should do, resulting in it doing rather a lot of different things Out-of-control inner classes Numerous static and instance methods Excessive numbers of convenience methods Cut-and-pasted code extract new class/subclass/interface pull up methods/fields
Long Parameter List
Method needs to much external information
replace parameter with method (receiver explicitly asks sender for data via sender getter method) replace parameters with a member fields in a dedicated object
Divergent Change
Same or related code appears all over the system Many different changes are necessary
Separate out the varying code into varying classes (extract class) that either subclass or are contained by the non-varying class Use Visitor or Self Delegation patterns
Feature Envy
Method in one class uses lots of pieces from another class
move method to the other class use Visitor or Self Delegation patterns
Data Clumps
Data that's always hanging with each other (e.g. name street zip) Extract out a class (extract class) for the data Related to long parameter list.
Introduce a Parameter Object Preserve whole object
Summary
Refactoring decreases cost of maintenance Refactoring preserves software behaviour Testing and analysis as methods of verification Code smells indicate a need for refactoring
Q&A