introduction to refactoring excerpted from ‘what is refactoring?’ by william c. wake and...

29
Introduction to Introduction to Refactoring Refactoring Excerpted from ‘What is Excerpted from ‘What is Refactoring?’ by William C. Refactoring?’ by William C. Wake and Wake and Refactoring: Improving the Refactoring: Improving the Design of Existing Code Design of Existing Code by Martin by Martin Fowler Fowler

Post on 15-Jan-2016

232 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Introduction to Introduction to RefactoringRefactoring

Excerpted from ‘What is Excerpted from ‘What is Refactoring?’ by William C. Wake Refactoring?’ by William C. Wake and and Refactoring: Improving the Refactoring: Improving the

Design of Existing CodeDesign of Existing Code by Martin by Martin FowlerFowler

Page 2: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

OutlineOutline

What is Refactoring?What is Refactoring? Why Refactor?Why Refactor? When to Refactor?When to Refactor? Why Refactoring Works?Why Refactoring Works? Bad SmellsBad Smells Types of RefactoringsTypes of Refactorings

Page 3: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

What is Refactoring?What is Refactoring?

The process of improving the design The process of improving the design of code without affecting its external of code without affecting its external behavior.behavior.

Refactor to keep your code as simple Refactor to keep your code as simple as possible.as possible.

Refactored code is clearer, simpler Refactored code is clearer, simpler and of higher quality.and of higher quality.

Refactoring is not performance Refactoring is not performance optimization.optimization.

Page 4: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

What is Refactoring? What is Refactoring? (cont…)(cont…)

Side EffectsSide Effects Often, code size is reducedOften, code size is reduced Confusing structures are transformed Confusing structures are transformed

into simpler constructsinto simpler constructs Lessons LearnedLessons Learned

Management buy-in is necessaryManagement buy-in is necessary Must follow systematic approach to Must follow systematic approach to

refactoringrefactoring

Page 5: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Why Refactor?Why Refactor?

Refactor to improve the design of Refactor to improve the design of software.software. Refactoring can “tidy up” sloppy code.Refactoring can “tidy up” sloppy code. Reducing the amount of code can make Reducing the amount of code can make

future modifications easier.future modifications easier. Refactoring makes code easier to Refactoring makes code easier to

understand.understand. Refactoring helps you find bugs.Refactoring helps you find bugs. Refactoring helps you program faster.Refactoring helps you program faster.

Page 6: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

When to Refactor?When to Refactor?

Refactoring is something you do all Refactoring is something you do all the time in small bursts.the time in small bursts.

The Rule of Three – Three strikes, The Rule of Three – Three strikes, you refactor.you refactor.

Refactor when you add features.Refactor when you add features. Refactor when you need to fix a bug.Refactor when you need to fix a bug. Refactor as you do a code review.Refactor as you do a code review.

Page 7: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Why Refactoring WorksWhy Refactoring Works

Programs that are hard to read are Programs that are hard to read are hard to modify.hard to modify.

Programs that have duplicated logic Programs that have duplicated logic are hard to modify.are hard to modify.

Programs that require additional Programs that require additional behavior that requires you to change behavior that requires you to change running code are hard to modify.running code are hard to modify.

Programs with complex conditional Programs with complex conditional logic are hard to modify.logic are hard to modify.

Page 8: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Bad SmellsBad Smells Duplicate CodeDuplicate Code Long MethodLong Method Large ClassLarge Class Long Parameter ListLong Parameter List Divergent Change – one type of change requires Divergent Change – one type of change requires

changing one subset of modules; another type of changing one subset of modules; another type of change requires changing another.change requires changing another.

Shotgun Surgery – the opposite of Shotgun Surgery – the opposite of divergent changedivergent change, a , a change requires a lot of little changes to a lot of change requires a lot of little changes to a lot of different classes.different classes.

Feature Envy – a method in a class seems to not belong.Feature Envy – a method in a class seems to not belong. Data Clumps –member fields that clump together but Data Clumps –member fields that clump together but

are not part of the same classare not part of the same class Primitive Obsession – characterized by the use of Primitive Obsession – characterized by the use of

primitives in place of class methods.primitives in place of class methods.

Page 9: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Bad Smells (cont…)Bad Smells (cont…) Switch Statements – often duplicated code that Switch Statements – often duplicated code that

can be replaced by polymorphism.can be replaced by polymorphism. Parallel Inheritance Hierarchies – duplicated code Parallel Inheritance Hierarchies – duplicated code

in subclasses that share a common ancestor.in subclasses that share a common ancestor. Lazy Class – a class that has little meaning in the Lazy Class – a class that has little meaning in the

of the software.of the software. Speculative Generality – methods (often stubs) Speculative Generality – methods (often stubs)

that are placeholders for future features.that are placeholders for future features. Temporary Field – a member variable that is only Temporary Field – a member variable that is only

used under certain circumstances.used under certain circumstances. Message Chains – object that requests an object Message Chains – object that requests an object

for another object which asks…for another object which asks…

Page 10: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Bad Smells (cont…)Bad Smells (cont…) Middle Man – a class that is just a “pass-through” Middle Man – a class that is just a “pass-through”

method with little logic.method with little logic. Inappropriate Intimacy – violation of private parts.Inappropriate Intimacy – violation of private parts. Alternate Class with Different Interfaces - two Alternate Class with Different Interfaces - two

methods that do the same thing, but have different methods that do the same thing, but have different interfaces.interfaces.

Incomplete Library Classes – a framework that Incomplete Library Classes – a framework that doesn’t do everything you need.doesn’t do everything you need.

Data Class – classes that have getters and setters, Data Class – classes that have getters and setters, but no real function.but no real function.

Refused Bequest – a subclass that over-rides most of Refused Bequest – a subclass that over-rides most of the functionality provided by its superclass.the functionality provided by its superclass.

Comments – text that explains bad code.Comments – text that explains bad code.

Page 11: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Types of RefactoringsTypes of Refactorings Moving Features Between ObjectsMoving Features Between Objects

Goal: ensure tight cohesionGoal: ensure tight cohesion Organizing DataOrganizing Data

Goal: encapsulate data appropriatelyGoal: encapsulate data appropriately Simplifying Conditional ExpressionsSimplifying Conditional Expressions

Goal: unclutter decision pointsGoal: unclutter decision points Making Method Calls SimplerMaking Method Calls Simpler

Goal: user parameterization sensiblyGoal: user parameterization sensibly Dealing With GeneralizationDealing With Generalization

Goal: use inheritance structure properlyGoal: use inheritance structure properly Big RefactoringsBig Refactorings

Goal: re-architect if necessaryGoal: re-architect if necessary Composing MethodsComposing Methods

Goal: ensure loose couplingGoal: ensure loose coupling

Page 12: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Moving Features Between Moving Features Between ObjectsObjects

Extract ClassExtract Class You have one class doing work that You have one class doing work that

should be done by two.should be done by two. Create a new class and move the Create a new class and move the

relevant fields and methods from the relevant fields and methods from the old class into the new class.old class into the new class.

SmellsSmells Large Class, Data ClumpsLarge Class, Data Clumps

Page 13: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Organizing DataOrganizing Data

Replace Magic Number with Replace Magic Number with Symbolic ConstantSymbolic Constant You have a literal number with a You have a literal number with a

particular meaningparticular meaning Create a constant, name it after the Create a constant, name it after the

meaning, and replace the number with meaning, and replace the number with it.it.

Page 14: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Simplifying Conditional Simplifying Conditional ExpressionsExpressions

Decompose ConditionalDecompose Conditional You have a complicated conditional (if-You have a complicated conditional (if-

then-else) statement.then-else) statement. Extract methods from the condition, Extract methods from the condition,

then part, and else parts.then part, and else parts.

Page 15: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Making Method Calls Making Method Calls SimplerSimpler

Rename MethodRename Method The name of a method does not reveal The name of a method does not reveal

its purpose.its purpose. Change the name of the method.Change the name of the method.

Page 16: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Dealing with Dealing with GeneralizationGeneralization

Extract SubclassExtract Subclass A class has features that are used only A class has features that are used only

in some instances.in some instances. Create a subclass for that subset of Create a subclass for that subset of

features.features.

Page 17: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Big RefactoringsBig Refactorings

Convert Procedural Design to Convert Procedural Design to ObjectsObjects You have code written in a procedural You have code written in a procedural

stylestyle Turn the data records into objects, Turn the data records into objects,

break up the behavior, and move the break up the behavior, and move the behavior to the objects.behavior to the objects.

Page 18: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Composing MethodsComposing Methods

Extract MethodExtract Method You have a code fragment that can be You have a code fragment that can be

grouped togethergrouped together Turn the fragment into a method whose Turn the fragment into a method whose

name explains the purpose of the name explains the purpose of the method.method.

SmellsSmells Large MethodLarge Method CommentsComments

Page 19: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Extract MethodExtract Method MechanicsMechanics

create new method create new method name by what it does, not how it does itname by what it does, not how it does it rule of thumb: if you can’t come up with a meaningful name, rule of thumb: if you can’t come up with a meaningful name,

then don’t extractthen don’t extract copy extracted code from source to targetcopy extracted code from source to target locate variables used in target but defined in source locate variables used in target but defined in source

scope. Choices:scope. Choices: if modified by target, consider method as a queryif modified by target, consider method as a query make variables params to methodmake variables params to method if can be used only in extracted code, make tempsif can be used only in extracted code, make temps

compile (and test, as appropriate)compile (and test, as appropriate) replace extracted code in source with callreplace extracted code in source with call

remove extraneous variablesremove extraneous variables compile and testcompile and test

Page 20: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Extract Method (cont…)Extract Method (cont…)void printOwing()void printOwing(){{

Enumeration e = _order.elements();Enumeration e = _order.elements();double outstanding = 0.0;double outstanding = 0.0;

System.out.println (“******************************”);System.out.println (“******************************”);System.out.println (“***** Customer Owes *****”);System.out.println (“***** Customer Owes *****”);System.out.println (“******************************”);System.out.println (“******************************”);

while (e.hasMoreElements())while (e.hasMoreElements()){{

Order each (Order) e.nextElement();Order each (Order) e.nextElement();outstanding += each.getAmount();outstanding += each.getAmount();

}}

System.out.println(“name: “ + _name);System.out.println(“name: “ + _name);System.out.println(“amount “ + outstanding);System.out.println(“amount “ + outstanding);

}}

“Islands” of abstraction

Page 21: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Extract Method (cont…)Extract Method (cont…)void printOwing()void printOwing(){{

Enumeration e = _order.elements();Enumeration e = _order.elements();double outstanding = 0.0;double outstanding = 0.0;

System.out.println (“******************************”);System.out.println (“******************************”);System.out.println (“***** Customer Owes *****”);System.out.println (“***** Customer Owes *****”);System.out.println (“******************************”);System.out.println (“******************************”);

while (e.hasMoreElements())while (e.hasMoreElements()){{

Order each (Order) e.nextElement();Order each (Order) e.nextElement();outstanding += each.getAmount();outstanding += each.getAmount();

}}

System.out.println(“name: “ + _name);System.out.println(“name: “ + _name);System.out.println(“amount “ + outstanding);System.out.println(“amount “ + outstanding);

}}

Page 22: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Extract Method (cont…)Extract Method (cont…)void printOwing()void printOwing(){{

Enumeration e = _order.elements();Enumeration e = _order.elements();double outstanding = 0.0;double outstanding = 0.0;

printBanner();printBanner();

while (e.hasMoreElements())while (e.hasMoreElements()){{

Order each (Order) e.nextElement();Order each (Order) e.nextElement();outstanding += each.getAmount();outstanding += each.getAmount();

}}

System.out.println(“name: “ + _name);System.out.println(“name: “ + _name);System.out.println(“amount “ + outstanding);System.out.println(“amount “ + outstanding);

}}

Page 23: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Extract Method (cont…)Extract Method (cont…)void printBanner()void printBanner(){{

System.out.println (“******************************”);System.out.println (“******************************”);System.out.println (“***** Customer Owes *****”);System.out.println (“***** Customer Owes *****”);System.out.println (“******************************”);System.out.println (“******************************”);

}}

Page 24: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Extract Method (cont…)Extract Method (cont…)void printOwing()void printOwing(){{

Enumeration e = _order.elements();Enumeration e = _order.elements();double outstanding = 0.0;double outstanding = 0.0;

printBanner();printBanner();

while (e.hasMoreElements())while (e.hasMoreElements()){{

Order each (Order) e.nextElement();Order each (Order) e.nextElement();outstanding += each.getAmount();outstanding += each.getAmount();

}}

System.out.println(“name: “ + _name);System.out.println(“name: “ + _name);System.out.println(“amount “ + outstanding);System.out.println(“amount “ + outstanding);

}}

Page 25: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Extract Method (cont…)Extract Method (cont…)void printOwing()void printOwing(){{

Enumeration e = _order.elements();Enumeration e = _order.elements();double outstanding = 0.0;double outstanding = 0.0;

printBanner();printBanner();

while (e.hasMoreElements())while (e.hasMoreElements()){{

Order each (Order) e.nextElement();Order each (Order) e.nextElement();outstanding += each.getAmount();outstanding += each.getAmount();

}}

printDetails(outstanding);printDetails(outstanding);}}

Page 26: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Extract Method (cont…)Extract Method (cont…)

void printDetails(double outstanding)void printDetails(double outstanding){{

System.out.println(“name: “ + _name);System.out.println(“name: “ + _name);System.out.println(“amount “ + outstanding);System.out.println(“amount “ + outstanding);

}}

Page 27: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Extract Method (cont…)Extract Method (cont…)void printOwing()void printOwing(){{

Enumeration e = _order.elements();Enumeration e = _order.elements();double outstanding = 0.0;double outstanding = 0.0;

printBanner();printBanner();

while (e.hasMoreElements())while (e.hasMoreElements()){{

Order each (Order) e.nextElement();Order each (Order) e.nextElement();outstanding += each.getAmount();outstanding += each.getAmount();

}}

printDetails(outstanding);printDetails(outstanding);}}

Page 28: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

Extract Method (cont…)Extract Method (cont…)void printOwing()void printOwing(){{

printBanner();printBanner();double outstanding = getOutstanding();double outstanding = getOutstanding();printDetails(outstanding);printDetails(outstanding);

}}

void getOutstanding()void getOutstanding(){{

Enumeration e = _order.elements();Enumeration e = _order.elements();double result = 0.0;double result = 0.0;while (e.hasMoreElements())while (e.hasMoreElements()){{

Order each (Order) e.nextElement();Order each (Order) e.nextElement();result += each.getAmount();result += each.getAmount();

}}return result;return result;

}}

Page 29: Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler

SummarySummary

Most code should be human-readable Most code should be human-readable first, machine readable second.first, machine readable second.

Refactoring improves code Refactoring improves code comprehension, thus making maintenance comprehension, thus making maintenance easier.easier.

Although identifying what to refactor is an Although identifying what to refactor is an art, the process of refactoring is very art, the process of refactoring is very algorithmic.algorithmic.

ALWAYS, ALWAYS TEST YOUR CODE ALWAYS, ALWAYS TEST YOUR CODE BEFORE AND AFTER YOU REFACTOR!BEFORE AND AFTER YOU REFACTOR!