2. Shit happens
Anything that can go wrong will go
AKA "fast, slow, slower.... never :("
 quickly deliver 1.0 release that works well for our
customers but with junky code
 working on 2.0 release, junky code slows you down,
and new features are harder to implement
 as junky code multiplies, people lose faith into the
system and the programmers
 planning next release, you realize you can't win, and
start thinking about a total rewrite
AKA "the 'HelloWorld' pattern"
 code more sophisticated that it possible future
 code hard to understand for new ones
 time wasted understanding and maintaining complex
code so you need to write documentation
5. Code smells
 copy/paste (duplicate) code
 large method/class
 method-like properties
 contrived complexity (patterns everywhere!)
 inappropriate intimacy
 unused code
 dangerous if (if - else if - else if - else...)
6. Cunningham's metaphor
The technical language doesn't communicate
effectively with the vast majority of management.
Instead, Ward Cunningham's financial metaphor of
design debt works infinitely better.
Design debt occurs when you don't consistently do
1. Remove duplication.
2. Simplify your code.
3. Clarify you code's intent.
7. Cunningham's metaphor
Few systems remain completely free of design debt.
Wired as we are, humans just don't write perfect code
the first time around. We naturally accumulate design
debt. So the question becomes:
"When do you pay it down?"
8. And so, refactoring!
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
A refactoring is a "behavior-preserving transformation"
or, as Martin Fowler defines it, "a change made to the
internal structure of software to make it easier to
understand and cheaper to modify without changing its
9. Why refactoring?
 Code i wrote yesterday is worse that code i'm writing
 Make it easier to add new code
 Improve the design of existing code
 Gain a better understanding of code
 Make coding less annoying
 Readability / Testability / Estensibility
 bugs correction
10. When refactoring?
 Keeping code clean is a lot like keeping a room
clean. Once your room becomes a mess, it becomes
harder to clean. The worse the mess becomes, the
less you want to clean it.
 It's best to refactor continuously, rather than in
phases. When you see code that needs
improvement, improve it.
 On the other hand, if your manager needs you to
finish a feature before a demo that just got
scheduled for tomorrow, finish the feature and
11. When NOT refactoring?
 If it's working, don't change
 if you have a poorly factored program
 if your code isn't tested, that does what the
customer wants and has no serious bugs, leave it
 performance matters...
12. How refactoring
 extract superclass/interface
 rename method/property/variable
 replace conditional with polymorphism
 replace constructor with factory method
 inline method
 even more: http://www.refactoring.com/catalog
13. How refactoring
Only refactor when refactoring -- do not add feature
Refactoring, or improving the design of existing code,
requires that you know what code needs improvement.
14. How refactoring
Each transformation (called a "Refactoring") does little,
but a sequence of transformations can produce a
The system is also kept fully working after each small
refactoring, reducing the chances that a system can
get seriously broken during the restructuring process.
15. How refactoring
If you want to refactor, the essential
precondition is having solid test
16. Test-Driven Development
Test-driven development (TDD) and continuous
refactoring enable the efficient evolution of working
code by turning programming into a dialogue.
17. Test-Driven Development
Ask: You ask a question of a system by writing a test.
Respond: You respond to the question by writing
code to pass the test.
Refine: You refine your response by consolidating
ideas, weeding out inessentials, and clarifying
Repeat: You keep the dialogue going by asking the
18. Refactoring and pattern
There is a natural relation between
patterns and refactorings. Patterns
are where you want to be;
refactorings are ways to get there
from somewhere else.
19. Refactoring and pattern
 Each pattern is a three-part rule, which expresses a
relation between a certain context, a problem, and a
 There are many ways to implement a pattern. If you
don't know patterns, you're less likely to evolve great
designs. Patterns capture wisdom. Reusing that
wisdom is extremely useful, also when refactoring.
 Refactoring: Improving the Design of Existing Code
 Refactoring to patterns
 Design Patterns: Elements of Reusable Object-
(Gang of Four)
 The Pragmatic Programmer
(Andrew Hunt and David Thomas)
21. The sage final sentence
Any fool can write code
that a computer can
programmers write code
that humans can