Download - Introduction to Refactoring
Introduction to Refactoring
About Me
Vorleak ChyEmail ([email protected])Yoolk Inc. (http://www.yoolk.com)Blog (http://vorleakchy.com)Rails Developer.NET Developer
What do we talk about Refactoring?
What? Why?
When? How?
Get Agile – Refactoring
Practices
Tools
What is Refactoring?
The process of changing a software system in such a way that it does not alter the external behavior of the code, yet improves its internal structure.
Fowler, et al., Refactoring, 1999.
Before
Unreadable codeDuplicated codeComplex codeHard to modify… More
After
Easier to understandClean codeBetter codeCheaper to modify… More
Why do we Refactor?
The realityExtremely difficult to get the design “right” the first timeHard to fully understand the problem domainHard to understand user requirements, even if the user does!Hard to know how the system will evolve in five yearsOriginal design is often inadequateSystem becomes brittle over time, and more difficult to change
Why do we Refactor? (Cont.)
Helps us to deliver more business values fasterImprove code structure and design
Easier to maintain and understandEasier to modifyMore flexibilityEasier to add new featuresIncreased re-usability
Why do we Refactor? (Cont.)
Keep development at speedTo make the software easier to understand
Write for people, not the compilerUnderstand unfamiliar code
To help us find bugsRefactor while debugging to clarify the code
Readability
Which code segment is easier to read?
if (date.before(Summer_Start) || date.after(Summer_End))charge = quantity * winterRate + winterServiceCharge;
elsecharge = quantity * summerRate;
Sample 1
Sample 2if (isSummer(date))
charge = summerCharge(quantity);else
charge = winterCharge(quantity);
When should we refactor?
Add new featuresFix bugsDuring code reviewOnly refactor when refactoring. Do not add features during refactoring
When Not to Refactor
Sometimes you should throw things out and start againSometimes you are too close to a deadline
Costs of Not Refactoring
Bad code usually takes more code to do the same thing often because of duplication
How do we Refactor?
We looks for Code-SmellsThings that we suspect are not quite right or will cause us severe pain if we do not fix
Common Code Smells
Duplicated codeFeature EnvyCommentsLong MethodLong parameter listSwitch Statements
Duplicated code
There is obvious duplicationSuch as copy and paste
There are unobvious duplicationsSuch as parallel inheritance hierarchiesSimilar algorithms
RemedyExtract MethodPull Up Field
Feature Envy
A method that seems more interested in some other classes than the one it is inRemedy
Move MethodExtract Method
Extract Methodvoid printOwning(double amount){
printBanner();
// print detailsSystem.Console.WriteLine(string.Format(“name: “, name);System.Console.WriteLine(string.Format(“amount: “, amount);
}
void printOwning(double amount){printBanner();printDetails(amount);
}
void printDetails(double amount){System.Console.WriteLine(string.Format(“name: “, name);System.Console.WriteLine(string.Format(“amount: “, amount);
}
Comments
Comments – be suspicious!Comments represent a failure to express an idea in the codeRemedy
Extract MethodRename Method
Long Method
Good OO code is easiest to understand and maintain with shorter methods with good namesLong methods tend to be harder to read and understandRemedy
Extract MethodReplace Temp with QueryReplace Method with Method ObjectDecompose Conditional
Replace Temp with Query
double basePrice = _quanity *_itemPrice;
if(basePrice > 1000) {return basePrice * 0.95;
}else {
return basePrice * 0.98;}
if(getBasePrice() > 1000) {return getBasePrice() * 0.95;
}else {
return getBasePrice() * 0.98;}
double getBasePrice() {return _quanitiy * _itemPrice;
}
Long parameter list
Functions should have as few parameters as possibleRemedy
Replace Parameter with MethodPreserve Whole ObjectIntroduce Parameter Object
Introduce Parameter Object
amountInvoicedIn(Date start, Date end)amountRecivedIn(Date start, Date end)amountOverdueIn(Date start, Date end)
Customer
amountInvoicedIn(DateRange range)amountRecivedIn(DateRange range)amountOverdueIn(DateRange range)
Customer
Switch Statements
Type cases are evil because they tend to be duplicated many timesRemedy
Replace Type Code with SubclassesReplace Type Code with State / StrategyReplace Conditional with PolymorphismReplace Parameter with Explicit MethodsIntroduce Null Object
Replace Parameter with Explicit Methods
void setValue(String name, int value){
if(name.Equals(“height”)){
_height = value;return;
}if(name.Equals(“width”)){ _width = value;
return; }
}
void setHeight(int value){
_height = value;}
void setWidth(int value){
_width = value;}
Refactoring Cycle
Choose on appropriate Refactoring
to apply
Apply Refactoring
Run ALL Tests (Get GREEN
Bar)
No
Yes
Reached Desired
Structure?
Demo
Q & A
Essential Reading
Thank you!