@rmarioo
QUIZ: Legacy code ?
A) Code difficult to change
B) Inherited code difficult to change
C) Valuable code we’re afraid to change
2
@rmarioo
Have you ever had these feelings ?
4
• Fear / Under pressure
.. so I do changes inside the existing code
• Nervous ( i depend on… )
“engaged” with debugger , complex infrastructure
• Unsafe
Did i broke something ? Is this working ?
• Resigned
“Edit and pray”
@rmarioo
You are in the Matrix
…. and you are feeding the monster !!!
Diagnosis…
5
Now take your choice..
@rmarioo
The journey …of facing legacy code
7
UNDERSTAND REFACTORCOVER
Each step has a different target.
Focus only on that target !
CHANGE
@rmarioo
• Use it
… before looking at the code!
• Find one thing you know
1. look for keywords
2. and trace the actions backward
Understand: How ?
8
@rmarioo
Cover: where should i start ?
11
if condition1
….
….
if condition2
…..
…..
if condition3
…..
…..
else
…..
…..
else
…..
…..
else
…..
…..
Start from shortest
to deepest branch
@rmarioo
Cover: test the unknown
12
We assume to know what the code is supposed
to do
… but what if we don’t ?
• Test name ???
• Expected result ???
@rmarioo
Cover: Exploratory testing
13
1. Write a test named “x”
2. Set any expected result
3. Run it and get a Failure
java.lang.AssertionError: expected:<null> but was:<plain text>
4. Copy the text and make it pass
5. Give a better name
@rmarioo
Shortcut: “Delimit your territory”
14
Extract the code you want to change in a separate
section
- Smaller problem to solve
- Quicker way to the coverage
@rmarioo
… some special licences
16
• Changes allowed only by IDE
refactoring
• Do not bother with code quality now
@rmarioo
Example : Subclass and override
1
7
public class A {
public void do1(…) {
user = session.getAttribute(“user”);
...
}
public class ATest
{
@Test
public void do1WhenLogged() { }
private class TestableA extends A
{
@Override
protected boolean isLogged()
{
return true
}
}
} public void do1(…) {
...
logged = isLogged(“mario")
}
protected Boolean isLogged(..)
TEST CODE SOURCE CODE
@rmarioo
LET A TEST GUIDE US …
HARD TO CREATE
OR MAKE IT PASS ?
REFACTOR
APPLY THE
CHANGE
ADD A TEST
@rmarioo
Refactor: where to start ?
20
if condition1
….
….
if condition2
…..
…..
if condition3
…..
…..
else
…..
…..
else
…..
…..
else
…..
…..
From deepest branch
@rmarioo
Yak shaving ..
21
@rmarioo
Pair programming can help!
22
• N: What are you doing?
• D: I am doing x and y and .. z
• N: Let’s choose one and complete it !
Write down x , y and z in the todo list
Single task editing allows to Getting things done
@rmarioo
Adding a new feature: a common mistake
23
“Let’s put new feature inside this existing method
because it should happen at the same time”
Problem : … test old and new code together
@rmarioo
Ex. adding new feature: "Sprout class"
24
1.
public void do1()
{
…
// new Feature(..).apply(…)
}
2. TDD
public class Feature
{
public void apply(…)
{
…
}
}3.
public void do1()
{
…
new Feature(..).apply(…)
}
@rmarioo
Pragmatic refactoring
25
• Stop when the change is easy to apply
• Effort proportional to code “liveness”
@rmarioo
Don’t repeat yourself!
26
• Split screen vertically TDD
• Continuous testing plugin
• Use shortcuts instead of repeating actions
• Small commits / steps
@rmarioo
Smells —> refactor —> steps & shortcuts
27
Show me the code !
https://github.com/rmarioo/smells-to-refactoring
@rmarioo
References
28
Books and publications
• Working Effectively with Legacy Code: Michael Feathers
• Refactoring: Improving the Design of Existing Code
• Sandro Mancuso – Testing and refactoring legacy code
• THE CODE WHISPERER - J. B. Rainsberger
Github projects
• Ugly trivia J. B. Rainsberger
• Videostore Robert Cecil Martin ( Uncle bob )
• Smells-to-refactoring Mario Russo