In questa sessione a quattro mani introdurremo alcuni dei refactorings più comuni e più facilmente applicabili nell'utilizzo quotidiano, e vedremo come risolverli in maniera facile, veloce ed indolore utilizzando ReSharper e pochi colpi di tastiera.
Incidentalmente, inseriremo nel mentre un pò di patterns e di Test-Driven Development, perchè "se non è testato, allora non funziona"
2. Shit happensShit happens
Anything that can go wrong will goAnything that can go wrong will go
wrong.wrong.
(Arthur Bloch)(Arthur Bloch)
3. UnderengineeringUnderengineering
AKA "fast, slow, slower.... never :("AKA "fast, slow, slower.... never :("
quickly deliver 1.0 release that works well for ourquickly deliver 1.0 release that works well for our
customers but with junky codecustomers but with junky code
working on 2.0 release, junky code slows you down,working on 2.0 release, junky code slows you down,
and new features are harder to implementand new features are harder to implement
as junky code multiplies, people lose faith into theas junky code multiplies, people lose faith into the
system and the programmerssystem and the programmers
planning next release, you realize you can't win, andplanning next release, you realize you can't win, and
start thinking about a total rewritestart thinking about a total rewrite
4. OverengineeringOverengineering
AKA "the 'HelloWorld' pattern"AKA "the 'HelloWorld' pattern"
code more sophisticated that it possible futurecode more sophisticated that it possible future
requirementsrequirements
code hard to understand for new onescode hard to understand for new ones
time wasted understanding and maintaining complextime wasted understanding and maintaining complex
code so you need to write documentationcode so you need to write documentation
5. Code smellsCode smells
copy/paste (duplicate) codecopy/paste (duplicate) code
large method/classlarge method/class
method-like propertiesmethod-like properties
contrived complexity (patterns everywhere!)contrived complexity (patterns everywhere!)
inappropriate intimacyinappropriate intimacy
unused codeunused code
dangerous if (if - else if - else if - else...)dangerous if (if - else if - else if - else...)
6. Cunningham's metaphorCunningham's metaphor
The technical language doesn't communicateThe technical language doesn't communicate
effectively with the vast majority of management.effectively with the vast majority of management.
Instead, Ward Cunningham's financial metaphor ofInstead, Ward Cunningham's financial metaphor of
design debt works infinitely better.design debt works infinitely better.
Design debt occurs when you don't consistently doDesign debt occurs when you don't consistently do
three things.three things.
1. Remove duplication.1. Remove duplication.
2. Simplify your code.2. Simplify your code.
3. Clarify you code's intent.3. Clarify you code's intent.
7. Cunningham's metaphorCunningham's metaphor
Few systems remain completely free of design debt.Few systems remain completely free of design debt.
Wired as we are, humans just don't write perfect codeWired as we are, humans just don't write perfect code
the first time around. We naturally accumulate designthe first time around. We naturally accumulate design
debt. So the question becomes:debt. So the question becomes:
"When do you pay it down?""When do you pay it down?"
8. And so, refactoring!And so, refactoring!
Refactoring is the process of changing a softwareRefactoring is the process of changing a software
system in such a way that it does not alter the externalsystem in such a way that it does not alter the external
behavior of the code yet improves its internalbehavior of the code yet improves its internal
structure.structure.
A refactoring is a "behavior-preserving transformation"A refactoring is a "behavior-preserving transformation"
or, as Martin Fowler defines it, "a change made to theor, as Martin Fowler defines it, "a change made to the
internal structure of software to make it easier tointernal structure of software to make it easier to
understand and cheaper to modify without changing itsunderstand and cheaper to modify without changing its
observable behavior"observable behavior"
9. Why refactoring?Why refactoring?
Code i wrote yesterday is worse that code i'm writingCode i wrote yesterday is worse that code i'm writing
todaytoday
Make it easier to add new codeMake it easier to add new code
Improve the design of existing codeImprove the design of existing code
Gain a better understanding of codeGain a better understanding of code
Make coding less annoyingMake coding less annoying
Readability / Testability / EstensibilityReadability / Testability / Estensibility
bugs correctionbugs correction
......
10. When refactoring?When refactoring?
Keeping code clean is a lot like keeping a roomKeeping code clean is a lot like keeping a room
clean. Once your room becomes a mess, it becomesclean. Once your room becomes a mess, it becomes
harder to clean. The worse the mess becomes, theharder to clean. The worse the mess becomes, the
less you want to clean it.less you want to clean it.
It's best to refactor continuously, rather than inIt's best to refactor continuously, rather than in
phases. When you see code that needsphases. When you see code that needs
improvement, improve it.improvement, improve it.
On the other hand, if your manager needs you toOn the other hand, if your manager needs you to
finish a feature before a demo that just gotfinish a feature before a demo that just got
scheduled for tomorrow, finish the feature andscheduled for tomorrow, finish the feature and
refactor later!refactor later!
11. When NOT refactoring?When NOT refactoring?
If it's working, don't changeIf it's working, don't change
if you have a poorly factored programif you have a poorly factored program
if your code isn't tested, that does what theif your code isn't tested, that does what the
customer wants and has no serious bugs, leave itcustomer wants and has no serious bugs, leave it
alone!alone!
performance matters...performance matters...
12. How refactoringHow refactoring
Refactoring recipesRefactoring recipes
extract superclass/interfaceextract superclass/interface
rename method/property/variablerename method/property/variable
replace conditional with polymorphismreplace conditional with polymorphism
replace constructor with factory methodreplace constructor with factory method
inline methodinline method
even more:even more: http://www.refactoring.com/cataloghttp://www.refactoring.com/catalog
13. How refactoringHow refactoring
Only refactor when refactoring -- do not add featureOnly refactor when refactoring -- do not add feature
during refactoring.during refactoring.
Refactoring, or improving the design of existing code,Refactoring, or improving the design of existing code,
requires that you know what code needs improvement.requires that you know what code needs improvement.
14. How refactoringHow refactoring
Each transformation (called a "Refactoring") does little,Each transformation (called a "Refactoring") does little,
but a sequence of transformations can produce abut a sequence of transformations can produce a
significant restructuring.significant restructuring.
The system is also kept fully working after each smallThe system is also kept fully working after each small
refactoring, reducing the chances that a system canrefactoring, reducing the chances that a system can
get seriously broken during the restructuring process.get seriously broken during the restructuring process.
15. How refactoringHow refactoring
If you want to refactor, the essentialIf you want to refactor, the essential
precondition is having solid testprecondition is having solid test
(Martin Fowler)(Martin Fowler)
16. Test-Driven DevelopmentTest-Driven Development
Test-driven development (TDD) and continuousTest-driven development (TDD) and continuous
refactoring enable the efficient evolution of workingrefactoring enable the efficient evolution of working
code by turning programming into a dialogue.code by turning programming into a dialogue.
17. Test-Driven DevelopmentTest-Driven Development
AskAsk: You ask a question of a system by writing a test.: You ask a question of a system by writing a test.
RespondRespond: You respond to the question by writing: You respond to the question by writing
code to pass the test.code to pass the test.
RefineRefine: You refine your response by consolidating: You refine your response by consolidating
ideas, weeding out inessentials, and clarifyingideas, weeding out inessentials, and clarifying
ambiguities.ambiguities.
RepeatRepeat: You keep the dialogue going by asking the: You keep the dialogue going by asking the
next question.next question.
18. Refactoring and patternRefactoring and pattern
There is a natural relation betweenThere is a natural relation between
patterns and refactorings. Patternspatterns and refactorings. Patterns
are where you want to be;are where you want to be;
refactorings are ways to get thererefactorings are ways to get there
from somewhere else.from somewhere else.
(Fowler Martin)(Fowler Martin)
19. Refactoring and patternRefactoring and pattern
Each pattern is a three-part rule, which expresses aEach pattern is a three-part rule, which expresses a
relation between a certain context, a problem, and arelation between a certain context, a problem, and a
solution.solution.
There are many ways to implement a pattern. If youThere are many ways to implement a pattern. If you
don't know patterns, you're less likely to evolve greatdon't know patterns, you're less likely to evolve great
designs. Patterns capture wisdom. Reusing thatdesigns. Patterns capture wisdom. Reusing that
wisdom is extremely useful, also when refactoring.wisdom is extremely useful, also when refactoring.
20. ReadingsReadings
Refactoring: Improving the Design of Existing CodeRefactoring: Improving the Design of Existing Code
(Martin Fowler)(Martin Fowler)
Refactoring to patternsRefactoring to patterns
(Joshua Kerievsky)(Joshua Kerievsky)
Design Patterns: Elements of Reusable Object-Design Patterns: Elements of Reusable Object-
Oriented SoftwareOriented Software
(Gang of Four)(Gang of Four)
The Pragmatic ProgrammerThe Pragmatic Programmer
(Andrew Hunt and David Thomas)(Andrew Hunt and David Thomas)
21. The sage final sentenceThe sage final sentence
Any fool can write codeAny fool can write code
that a computer canthat a computer can
understand. Goodunderstand. Good
programmers write codeprogrammers write code
that humans canthat humans can
understand.understand.
(M. F.)(M. F.)
23. The Must-Have Productivity Tool for .NET DevelopersThe Must-Have Productivity Tool for .NET Developers
PROsPROs
intellisenseintellisense
code searchcode search
test runnertest runner
code generationcode generation
background analysisbackground analysis
CONsCONs
commercial licensecommercial license
needs a lot of ram!needs a lot of ram!
a little bit buggya little bit buggy