software refactoring part i: introduction bartosz walter advanced object-oriented design lecture 5
TRANSCRIPT
Software RefactoringSoftware RefactoringPart I: IntroductionPart I: Introduction
Bartosz Walter<[email protected]>
Advanced Object-Oriented DesignLecture 5
MottoMotto
„Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
Martin Fowler
AgendaAgenda
1. Refactoring: ideas, motivation, examples2. Verification of refactorings3. Bad smells in code
More functionality!More functionality!
Oh, I've found a bug...Oh, I've found a bug...
We've got no time. Let's integrate...We've got no time. Let's integrate...
Motivation for refactoringMotivation 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 = You Aren't Going to Need It
RefactoringRefactoring
a change made to the internal structure of software
void doSth()void doSth()
to make it easier to understand and cheaper to modify without changing its observable behaviour
Refactoring is:Refactoring is:
Source: W. Opdyke
Simplest exampleSimplest example
Extract MethodExtract Method
void compAndPrint() { // compute X // compute Y ... // print X // print Y ... // store X // store Y}
void compute () { // compute X // compute Y print(X, Y); // store X // store Y}
void print(X,Y) { // print X // print Y}
One method – one functionOne method – one function Allows localizing the potential bugsAllows localizing the potential bugs
Simplest example (reverted)Simplest example (reverted)
Inline MethodInline Method
void compAndPrint() { ... X++; Y++; ...}
void compute () { X = next(X); Y = next(Y);}
int next(N) { return N++;}
Removal of very short methodsRemoval of very short methods
Cost of refactoringCost of refactoring
The cost depends on: the language used support from CASE tools the type of refactorings number and quality of test cases
Refactoring is costly because it does not add new functions to the system.
Important factors: cost of documentation update cost of test cases update
When When to doto do and and not donot do refactoring? refactoring?
Three strikes and refactorThree strikes and refactor When adding new When adding new
functionsfunctions When fixing a bugWhen fixing a bug While inspecting codeWhile inspecting code
At close deadlinesAt close deadlines Prematurely published Prematurely published
interfacesinterfaces Unstable, rubbish codeUnstable, rubbish code
Unfinished refactoring is like going into debt. You can live with it, but it is costly.
Ward Cunningham
Verification of refactoringsVerification of refactorings
Automated verification
Implemented in many IDEs
Verification requires testing
Tests need to be manually created
SIMPLE HARD
Simple refactorings...Simple refactorings...
void doSth()void doSth()
If before....If before....
Verification of pre-conditions Static analysis of code
Then after....Then after....
... and hard ones... and hard ones
Static code analysis, preconditions Role of unit tests
void doSth()void doSth()
If before....If before....
Then after....Then after....
Bad smellsBad smells
If it stinks, change it
Kent Beck grandmadiscussing child-rearing philosophy
Duplicated CodeDuplicated 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 MethodLong 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 classLarge 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 ListLong 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 ChangeDivergent Change
Same or related code appears all over the systemMany 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 EnvyFeature 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 ClumpsData 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
SummarySummary
Refactoring decreases cost of Refactoring decreases cost of maintenancemaintenance
Refactoring preserves software Refactoring preserves software behaviourbehaviour
Testing and analysis as methods of Testing and analysis as methods of verificationverification
Code smells indicate a need for Code smells indicate a need for refactoringrefactoring
Q&AQ&A