refactoring - universidade nova de lisboa · 2009. 12. 14. · arie van bennekum brian marick dave...
TRANSCRIPT
1
Refactoring
Fernando Brito e Abreu
FCT / Universidade Nova de LisboaQUASAR Research Group
Agenda
Motivation
Agile methodologies and the Agile Manifesto
eXtreme Programming (XP) and Refactoring
What is Refactoring?
Why Refactor?
When to and not to Refactor?
How to Refactor? Examples
Why are developers reluctant?
Refactorings Catalog
IDE Tools SupportRefactoring / Fernando Brito e Abreu 214-Dec-09
Market forces
Sw development in an ―on demand‖ business
Make it work, make it right, make it fast!
Less is More, Just Enough Development, Deliver
Value
Deliver early, get feedback, deliver often
Embracing change – requirements, goals, etc…
Refactoring / Fernando Brito e Abreu 314-Dec-09
Complexity affects maintenance costs
Incredible complexity of commercial systems
It is often easier to adapt business processes and organization
to Information Technology than the other way around
See Laws of Software Evolution by Manny Lehman
Refactoring / Fernando Brito e Abreu 414-Dec-09
The cost of a change escalates along
the life cycle. Both books refer it!
Revolution or Reform?
Revolution The only truth in legacy systems is the one embedded in code
Too messy code -> better to start from the beginning
Reform Since changes are inevitable, reduce their cost by producing
more maintainable, extensible and scalable software
This is where refactoring comes in!
Is refactoring new for you? No!
Refactoring / Fernando Brito e Abreu 514-Dec-09
Analogy – Database Normalization First Normal Form (1NF) — This rule has several requirements, including that
there are no multivalued items or repeating groups; that each field is atomic, meaning each field must contain the smallest data element possible; and that the table contains a key.
Second Normal Form (2NF) — The table must be normalized to 1NF. All fields must refer to (or describe) the primary key value. If the primary key is based on more than one field, each nonkey field must depend on the complex key, not just one field within the key. Nonkey fields that don't support the primary key should be moved to another table.
Third Normal Form (3NF) — The table must meet 1NF and 2NF requirements. All fields must be mutually independent. Any field that describes a nonkey field must be moved to another table.
Boyce-Codd Normal Form (BCNF) — There must be no possibility of a nonkey dependent field occurring. This rule is really a subrule of 3NF and supposedly catches dependencies that might otherwise sneak through the process. It's rather abstract and can be difficult to apply at first.
Refactoring / Fernando Brito e Abreu 614-Dec-09
2
Analogy continued
Each field must be as small as possible
Each field can contain only one data item
Each record should be unique
Watch for repeating entries
Each field must fully support the primary key, and
only the primary key
Refactoring / Fernando Brito e Abreu 714-Dec-09 Refactoring / Fernando Brito e Abreu 814-12-2009
Origins of agile methodologies
Project StartPlanned Result
Final Result
Refactoring / Fernando Brito e Abreu 914-12-2009
Origins of agile methodologies
Agility The ability to both create and respond to change in order to
profit in a turbulent business environment Companies need to determine the amount of agility they need to be
competitive
Chaordic (ex: agile view) Exhibiting properties of both chaos and order
The blend of chaos and order inherent in the external environment and in people themselves, argues against the prevailing wisdom about predictability and planning
Things get done because people adapt, not because they slavishly follow processes
An agile view is a chaordic view
Refactoring / Fernando Brito e Abreu 1014-12-2009
Manifesto for Agile Software Development
Alistair CockburnAndrew HuntArie van BennekumBrian MarickDave Thomas James GrenningJeff SutherlandJim Highsmith
Jon Kern Ken SchwaberKent Beck Martin FowlerMike BeedleRobert C. Martin Ron JeffriesSteve MellorWard Cunningham
February 11-13, 2001, The Lodge at Snowbird ski resort in the Wasatch mountains of Utah
Refactoring / Fernando Brito e Abreu 1114-12-2009
The Agile Manifesto
“We are uncovering better ways of developing software by doing it and helping others do it.
Through this work we have come to value:
Individuals and interactions over processes and toolsWorking software over comprehensive documentation
Customer collaboration over contract negotiationResponding to change over following a plan
That is, while there is value on the items on the right,we value the items on the left more.”
Refactoring / Fernando Brito e Abreu 1214-12-2009
Individuals and interactionsover processes and tools
Promote teambuilding and mutual trust
Build projects around motivated individuals
Give team members the environment and support they need, and trust them to get the job done
Adopt a barely sufficient methodology ―the conventions we agree to‖
Processes are described in manuals; practices are what happen in reality
3
Refactoring / Fernando Brito e Abreu 1314-12-2009
Working softwareover comprehensive documentation
Our highest priority is to satisfy the customer through
early and frequent delivery of valuable software
Deliver working software frequently, from a couple of
weeks to a couple of months, with a preference for the
shorter time scale
Working software/product is the primary measure of
progress
Refactoring / Fernando Brito e Abreu 1414-12-2009
Customer collaborationover contract negotiation
Set an open tone with the customer(s) organization(s)
Adopt collaborative values and principles
Business people and developers work together daily
throughout the project
Refactoring / Fernando Brito e Abreu 1514-12-2009
Responding to changeover following a plan
Being agile means accepting that outcomes are not
predictable and that processes are not repeatable
Welcome changing requirements, even late in
development
Agile processes harness change for the customer’s
competitive advantage
Agility is about adaptability rather than predictability
Agile Software Development Approaches Agile Modeling
Agile Unified Process (AUP)
Agile Data Method
DSDM
Essential Unified Process (EssUP)
Extreme programming (XP)
Feature Driven Development (FDD)
Getting Real
Open Unified Process (OpenUP)
Scrum
Lean software developmentRefactoring / Fernando Brito e Abreu 1614-Dec-09
Refactoring / Fernando Brito e Abreu 1714-12-2009
XP is a widespread agile approach!
Refactoring / Fernando Brito e Abreu 1814-12-2009
XP programming practices
Pair programming
Test-first design
Refactoring
Continuous integration
Collective ownership
Coding standard
40 hour week
4
XP and Refactoring
Refactoring is part of XP:
Refactoring can be carried out without XP, but it has additional
value with XP
It has similar targets to those that XP inspires
When refactoring is part of XP:
refactoring becomes part of the routine
it stops feeling like an overhead activity
Refactoring / Fernando Brito e Abreu 1914-Dec-09
XP and Refactoring
Refactoring / Fernando Brito e Abreu 2014-Dec-09
Source: Beck, K. (2000).
eXtreme Programming
explained, Addison Wesley.
Mutual relationships of
refactoring and other
XP practices
What is Refactoring
Refactoring / Fernando Brito e Abreu 2114-Dec-09
“ Refactoring is the process of taking a running
program and adding to its value, not by changing its
behavior but by giving it more of these qualities that
enable us to continue developing at speed.”
(Kent Beck, p. 51)
“Refactoring is 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, to make it easier to understand
and cheaper to modify.
It is a disciplined way to clean up code that
minimizes the chances of introducing bugs. In
essence when you refactor you are improving the
design of the code after it has been written.”(Martin Fowler, p.53)
What is Refactoring
Refactoring / Fernando Brito e Abreu 2214-Dec-09
“Refactoring may be the single most important technical factor in achieving agility” (p. 155)
“Refactoring keeps you ready for change by keeping you comfortable with changing your code” (p. 189)
A change to the system that leaves its behavior unchanged, but enhances some nonfunctional quality – simplicity, flexibility, understandability, performance” (p. 179)
Refactoring: combined definition
Changes made to the system that:
Do not change observable behavior (all the tests still pass)
Remove duplication or needless complexity
Enhance software quality
Make the code simpler and easier to understand
Make the code more flexible
Make the code easier to change
Refactoring / Fernando Brito e Abreu 2314-Dec-09
Refactoring Metaphor 1
See refactoring as an health improvement program:
exercises and eating a proper diet
The culture we live in (consumptive society)
We can always make excuses, but we are only fooling ourselves
if we continue to ignore good behavior
Near-term and long-term benefits …
Refactoring / Fernando Brito e Abreu 2414-Dec-09
5
Refactoring Metaphor 2
―Refactoring is like continuing repair of a living
system. The goal is to stay within reasonable
operating limits with limited continual damage.
By staying within these limits you keep costs
low, because costs relate nonlinearly to the
amount of repair necessary. It is like
maintaining your house. You are best off
(financially) if you continuously maintain rather
than do large lump repairs.”
(Dirk Riehle)
Refactoring / Fernando Brito e Abreu 2514-Dec-09
Why Refactor
Main aspects: Simplifies the code
Increases code readability and understandability
Facilitates code extension
Reduces debugging effort
Prevents ―design decay‖ that occurs as changes are made
Cleans up messes in the code
But also: Continuous learning process about the target application and
good design and coding practices (and it looks good on your CV)
Redoing is fundamental to every creative processRefactoring / Fernando Brito e Abreu 2614-Dec-09
When to Refactor
When adding new functionalities
When fixing bugs
Before code reviews
To improve understanding for other reviewers
When you find ―code smells‖
There are catalogs to help us find them
Refactoring / Fernando Brito e Abreu 2714-Dec-09
In duplications use the ―Third Time‖ rule:Duplicate code once, refactor the next time!
Code Smells … Anything that:
is duplicated
is long and/or complex
does very little
is similar to something else
requires sets of changes to different things
has conditional control flow
has speculative generality There in case you need to have it someday
has excessive indirection
requires unnecessary knowledge about other objects
etc …
Refactoring / Fernando Brito e Abreu 2814-Dec-09
More on smells to
be described ahead!
When Not to Refactor
Published interfaces (APIs) and database schemas
Refactoring will cause problems for the code that uses them
When code is too broken and / or the test battery
doesn’t run (or is incomplete, or even absent)
Code must work correctly before refactoring
When someone else is working in the same code
When too close to a deadline
Refactoring requires overhead
Refactoring / Fernando Brito e Abreu 2914-Dec-09
Taken too far, refactoring can
lead to incessant tinkering with
the code, trying to make it perfectDangerous if you are a perfectionist!
Refactoring / Fernando Brito e Abreu 3014-12-2009
How to Refactor
Generalize where possible, add flexibility
Redistribute classes, variables and methods in order to
facilitate future adaptations and extensions
Remove all duplications
…
There are many more refactoring techniques, each
trying to correct or mitigate specific code smells
We should use a catalog that identifies the adequate
refactoring(s) for each code smell
Let’s see some examples taken from Fowler’s ―bible‖…
6
How to Refactor
Refactoring / Fernando Brito e Abreu 3114-Dec-09
Code Smell: Duplicated Code
“If you see the same code structure in more than one place,
you can be sure that your program will be better if you find
a way to unify them”.
Refactoring: Extract Method
When you have the same expression in two methods of the
same class.
How to Refactor
Refactoring / Fernando Brito e Abreu 3214-Dec-09
Code Smell: Long Method
“The longer the procedure is, the more difficult it is to
understand”.
Refactoring: Extract Method
Find parts of the methods that seem to go nicely together
and make a new method..
How to Refactor
Refactoring / Fernando Brito e Abreu 3314-Dec-09
Code Smell hints:
“A comment is a good place to say why you did something.
This kind of information helps future modifiers. When you
feel the need to write a comment, first try to refactor the
code so that any comment becomes superfluous.‖
Alternative Refactorings:
If you need a comment to explain what a block of code
does, try Extract Method. If the method is already
extracted but you still need a comment to explain what it
does, use Rename Method.
Refactoring ExampleExtract MethodWhen:
You have a code fragment that can be grouped together in a method
Rules:
Name it by what it does
Pass in any local variables it may need reference to from enclosing method
Replace code in original method by call to new method
Refactoring / Fernando Brito e Abreu 3414-Dec-09
ATTENTION: the same refactoring (here the Extract Method)
can be used to mitigate several code smells (Long Method,
Duplicated Code and Comments in previous slides)
Refactoring ExampleExtract Method
Refactoring / Fernando Brito e Abreu 3514-Dec-09
// Assume all are instance
variables
void f() { ...
// Compute score
score = a * b + c;
score -= discount;
}
void f() {
...
computeScore();
}
void computeScore() {
score = a * b + c;
score -= discount;
}
f is doing multiple tasks,
including computing score
Make computeScore a new
method in the same class
Refactoring ExampleRemove Assignments to Parameters
When:
Code assigns a value to a method parameter
Rules:
Create temp variable for parameter
Replace references to parameter with temp
variable after assignment
Change assignments to temp variable
Refactoring / Fernando Brito e Abreu 3614-Dec-09
7
Refactoring ExampleRemove Assignments to Parameters
Refactoring / Fernando Brito e Abreu 3714-Dec-09
int discount (int inputVal, int quantity, int yearToDate) {
if (inputVal > 50)
inputVal -= 2;
int discount (int inputVal, int quantity, int yearToDate) {
int result = inputVal;
if (inputVal > 50)
result -= 2;
Code assigns
to a parameter
Code uses
temp variableMore details in:
http://www.xp123.com/xplor/xp0002b/index.shtml
Why are developers reluctant?
Management factors:
Refactoring is an overhead activity. Who pays for it?
I am paid to write new, revenue-generating features …
How do I tell my manager that I did not do it right in
the first place?
How can you support its need while your backlog of
required features is growing?
Refactoring / Fernando Brito e Abreu 3814-Dec-09
Treat refactoring as part of the profession: This is how you
develop code. It should not be viewed as an additional work.
Why are developers reluctant?
It should be executed when the code runs and all the
tests pass. It seems that time is wasted now …
If the benefits are long-term, why exert the effort now?
In the long term I may not be with the project to reap the
benefits (short term focus) …
Learning resistance: refactoring techniques take some
time to be understood. I don’t have spare time to learn!
Refactoring may break a program that is working well …(Opdyke, in Fowler’s book, p. 313)
Refactoring / Fernando Brito e Abreu 3914-Dec-09
Refactoring may break the existing program…
How to reduce the risk of breaking code?
To have a thorough set of unit tests: the code should
pass the tests both before and after refactoring
To use an automated tool, such as Eclipse's
refactoring features, to perform this refactoring
Refactoring / Fernando Brito e Abreu 4014-Dec-09
Refactoring Life-Cycle
Refactoring / Fernando Brito e Abreu 4114-Dec-09
Ensure all
tests pass
Implement
refactoring
Determine
refactoring
Find code
that smells
Start
Most time, refactoring implies
small and local changes!
Add new functionalities
and update test battery
Stop
Refactoring usually
progresses in small,
iterative steps, until
known smells are gone
Determine how to simplify this code (use a catalog here)
TDD + Automated Refactoring
The combination of thorough testing and automated
refactoring is especially powerful
This ability to change the structure of your code without
altering its functionality, quickly and safely, in order to
add functionality or improve its maintainability can
dramatically affect the way you design and develop code
Refactoring / Fernando Brito e Abreu 4214-Dec-09
8
Requirements for Refactoring
Collective code ownership
Coding standards
Pair programming
Simple design
Tests
Continuous integration
Rested programmers
Refactoring / Fernando Brito e Abreu 4314-Dec-09
(Beck, page 66)
Fowler’s Refactorings Catalog Add Parameter
Change Bidirectional Association to Unidirectional
Change Reference to Value
Change Unidirectional Association to Bidirectional
Change Value to Reference
Collapse Hierarchy
Consolidate Conditional Expression
Consolidate Duplicate Conditional Fragments
Convert Dynamic to Static Construction by G. M. Davison
Convert Static to Dynamic Construction by G. M. Davison
Decompose Conditional
Duplicate Observed Data
Encapsulate Collection
Encapsulate Downcast
Encapsulate Field
Extract Class
Extract Interface
Extract Method
Extract Package by G.M. Davison
Extract Subclass
Extract Superclass
Form Template Method
Hide Delegate
Hide Method
Inline Class
Inline Method
Inline Temp
Introduce Assertion
Introduce Explaining Variable
Introduce Foreign Method
Introduce Local Extension
Introduce Null Object
Introduce Parameter Object
Move Class by Gerard M. Davison
Move Field
Move Method
Parameterize Method
Preserve Whole Object
Pull Up Constructor Body
Pull Up Field
Pull Up Method
http://www.refactoring.com/catalog/index.html44
Push Down Field
Push Down Method
Reduce Scope of Variable by Mats Henricson
Remove Assignments to Parameters
Remove Control Flag
Remove Double Negative by Ashley Frieze and M. Fowler
Remove Middle Man
Remove Parameter
Remove Setting Method
Rename Method
Replace Array with Object
Replace Assignment with Initialization by M.Henricson
Replace Conditional with Polymorphism
Replace Conditional with Visitor by Ivan Mitrovic
Replace Constructor with Factory Method
Replace Data Value with Object
Replace Delegation with Inheritance
Replace Error Code with Exception
Replace Exception with Test
Replace Inheritance with Delegation
Replace Iteration with Recursion by Dave Whipp
Replace Magic Number with Symbolic Constant
Replace Method with Method Object
Replace Nested Conditional with Guard Clauses
Replace Parameter with Explicit Methods
Replace Parameter with Method
Replace Record with Data Class
Replace Recursion with Iteration by Ivan Mitrovic
Replace Static Variable with Parameter by M.Vittek
Replace Subclass with Fields
Replace Temp with Query
Replace Type Code with Class
Replace Type Code with State/Strategy
Replace Type Code with Subclasses
Reverse Conditional by Bill Murphy and M. Fowler
Self Encapsulate Field
Separate Query from Modifier
Split Loop by Martin Fowler
Split Temporary Variable
Substitute Algorithm
45
Fowler’s Refactorings Catalog Refactorings Catalog for J2EE
Eliminate Inter-Entity Bean Communication
Hide presentation tier-specific details from business tier
Introduce A Controller
Introduce Business Delegate
Introduce Synchronizer Token
Localize Disparate Logic
Merge Session Beans
Move Business Logic to Session
Separate Data Access Code
Use a Connection Pool
Wrap entities with session
46Refactoring / Fernando Brito e Abreu14-Dec-09
IDE Support
Eclipse
Refactoring for Everyone
Explore refactoring functions in Eclipse JDT
IntelliJ
Multi-language Refactorings
VisualWorks (Smalltalk)
Refactoring BrowserRefactoring / Fernando Brito e Abreu 4714-Dec-09
More Information
Canonical Text:
―Refactoring – Improving the Design of Existing
Code‖, Martin Fowler, ISBN 0-201-48567-2
Canonical Website:
http://www.refactoring.com/
Refactoring / Fernando Brito e Abreu 4814-Dec-09