Prototyping
Evolution
Consolidation
University of Nantes – LS2N, France
Gerson Sunyé gerson.sunye@univ-nantes.fr

Introduction
Refactoring Operations
When to Refactor
Why Refactor
Refactor to Improve Extensibility
Refactor to Improve Maintainability
Integrate Refactoring to Software Development Process
Automatization
Conclusion
Software is never finished.
Software maintenance is just continuous development.
Consequence: code becomes complex and brittle
Original design is always inadequate.
Even good designers cannot:
get right the first time.
predict how the software will evolve.
understand correctly the problem domain and user requirements.
— Grow, don’t build software.

Prototyping
Evolution
Consolidation

Solidifies user requirements
Sketches the initial software design

Adds new functionalities.
Determines expansion points (hot-spots).

Corrects defects
Introduces new abstractions
A program transformation that preserves the visible behavior.
The activity of improving the design of a software source code.
Class rename
public class Stuff {
// (...)
}public class ConfigurationManager {
// (...)
}Insert intermediate class
public class Root {}
public class ConcreteA extends Root {}
public class ConcreteB extends Root {}public class Root {}
public class IntermediateClass extends Root {}
public class ConcreteA extends IntermediateClass {}
public class ConcreteB extends IntermediateClass {}Software maintenance and evolution
Software application development
Software framework development
The eternal quest for code uniqueness
The code is read and modified more often than it is written
Understand an existing design is hard
Modify an existing design is even harder
Code changes may introduce errors, defeating the propose.
Results are not visible.
Every software project is under time pressure.
Developers are paid to add new features.
Refactoring can be very expensive.
Design becomes more corrupt and code becomes more brittle.
Changes become more expensive and more frequent and are made quickly and poorly.
Gradually change the code to get a healthy design.
Design is done continuously.
By building the system, we discover how to improve it.
Introduction
Refactoring Operations
When to Refactor
Why Refactor
Refactor to Improve Extensibility
Refactor to Improve Maintainability
Integrate Refactoring to Software Development Process
Automatization
Conclusion
Simple source-to-source transformation with no visual effect.
Since refactoring operations are behavior-preserving, they can be composed and still preserve behavior.
Learning refactoring operations is similar to learning simple arithmetics.
Each refactoring operation has a set of preconditions
That is, the conditions that one should respect to perform the transformation
The precondition to the operation remove attribute is that the attribute is not used.
Add entity
Remove entity
Rename entity
Move entity
Intra-method
Composite operations
Add an attribute (instance or class level)
Add a class
Add a method (instance or class level)

Remove an attribute (instance or class level)
Remove a class
Remove a method (instance or class level)
public class Example {
private String name;
public neverUsedMethod() {
doNothing();
}
}Rename a variable
Rename an attribute (instance or class level)
Rename a class
Rename a method (instance or class level)
Change a method signature:
rename, permute, add, or remove arguments.
public class Example {
private String maeby;
public myMethod() {
String maybe;
this.call(maeby, me);
}
public call(String one, String other) {
doSomething();
}
}
Attribute push-down or pull-up (instance or class level).
Method push-down or pull-up (instance or class level).
Move attribute or method to another class

Extract code as method
Extract code as temporary variable
Inline method
Inline temporary variable
int increment(int i) {
return i+1;
}
void m() {
int a;
a = increment(a);
}void m() {
int a;
a = a + 1;
}Encapsulate attribute
Make attribute read-only
Extract interface from class
Extract inner class
Create template method
class A {
public int code;
}class A {
private int code;
public int getCode() {return code;}
public void setCode(int i) {code = i;}
}Change entity visibility
Introduce factory method
Convert variable to attribute
class A {
public A(int i, String s, float f) {}
}class A {
private A(int i, String s, float f) {}
public static createA(int i, String s, float f) {
return new A(i, s, f);
}
}Introduction
Refactoring Operations
When to Refactor
Why Refactor
Refactor to Improve Extensibility
Refactor to Improve Maintainability
Integrate Refactoring to Software Development Process
Automatization
Conclusion
Extend and then refactor
Refactor to extend
Debug and then refactor
Refactor to debug
Refactor to understand
Find a class or method with similar behavior and copy it
Make it work
Eliminate redundancy
Refactor the current design to make the change easy
Make the change
Locate and fix the bug
Add assertions
Extract method
Assign meaningful names
Create explaining constants for magic numbers
Create explaining constants or variables for complex expressions
Before debugging, refactor to simplify complex code
Then, debug it
Split large methods
Create explaining constants or variables for magic numbers
Assign meaningful names
Do not worry about performance
Introduction
Refactoring Operations
When to Refactor
Why Refactor
Refactor to Improve Extensibility
Refactor to Improve Maintainability
Integrate Refactoring to Software Development Process
Automatization
Conclusion
Refactor code before code extension
Separate things that change from things that do not.
Apply design patterns.
| Variability point | Design Pattern |
|---|---|
Algorithms | Strategy, Visitor |
Actions | Command |
Implementation | Bridge |
Response to change | Observer |
Interactions between objects | Mediator |
| Variability point | Design Pattern |
|---|---|
Object being created | Factory Method, Abstract Factory, Prototype |
Structure being created | Builder |
Traversal Algorithm | Iterator |
Object Interfaces | Adapter |
Object Behavior | Decorator, State |
public class Client {
public void writeAsciiOn(OutputStream o) {
o.print("name: ");
o.print(this.name);
(...)}
}Suppose that we want to print in HTML, XML, JSON, etc.
Create AsciiStrategy class
Add instance attribute to class Client and initialize it to AsciiStrategy
Move method writeAsciiOn() to class AsciiStrategy
Rename method writeAsciiOn() to writeOn()
public class Client {
private WriteStrategy writeStrategy = new AsciiStrategy();
public void writeOn(OutputStream o) {
writeStrategy.writeOn(this, o)}
}
public class AsciiStrategy {
public void writeOn(Client c, OutputStream o)
o.print("name: ");
o.print(c.name);
(...)}
}The printing behavior was extracted from the class Client.
Adding new printing behavior could be easily achieved.

Introduction
Refactoring Operations
When to Refactor
Why Refactor
Refactor to Improve Extensibility
Refactor to Improve Maintainability
Integrate Refactoring to Software Development Process
Automatization
Conclusion
Use Code Smells to find where the code should be improved
Long Method
Large Class
Long Parameter List
Nested Conditionals
Parallel Inheritance Hierarchies
Duplicated Code
Speculative Generality
Extract code snippets as smaller methods:
If an entire method is long and low-level, find the sequence of higher-level steps.
Comments in the middle of a method often point out good places to extract.
Smaller methods can often be reused
Create compositions of smaller classes
Find logical sub-components of the original class and create classes to represent them
Move methods and attributes into the new components
Related refactoring operations: Extract Class, Extract Subclass
Create a class containing all interrelated parameters.
Use this class as a parameter
Find methods that should be in the new class
If the conditional expression involves type test (isKindOf(), type(), getClass(), etc.), put the method on that class.
If the expression involves null objects (isEmpty(), isNull(), null, empty()), consider the Null Object pattern.
Use Move Method and Move Attribute to combine the hierarchies into one.
Push-up identical methods to common superclass
Push-up the more general method
Move the method into a common component (e.g., Strategy)
Related refactoring operations: Extract Method, PullUp Method, Form Template Method
Remove unnecessary delegation with Inline Class
Remove (almost) empty abstract classes
Remove unused parameters
Methods named with odd abstract names should be brought down to earth with Rename Method
Introduction
Refactoring Operations
When to Refactor
Why Refactor
Refactor to Improve Extensibility
Refactor to Improve Maintainability
Integrate Refactoring to Software Development Process
Automatization
Conclusion
Quick and dirty coding is like taking out a loan
Living with bad code is the interest
Debt is necessary for a business
Too much debt is not healthy and will eventually catch up to you
Little more breathing room
The design is still fresh in your mind
Listen
Test
Code
Refactor Continually
Some of the principles still apply, even if you’re not extreme
Whenever something seems difficult or awkward, refactor to make it easy
Let the program tell you where it needs to be fixed
If you cut and paste, you must refactor
Introduction
Refactoring Operations
When to Refactor
Why Refactor
Refactor to Improve Extensibility
Refactor to Improve Maintainability
Integrate Refactoring to Software Development Process
Automatization
Conclusion
Safe refactoring needs tests
Tests must pass before and after each refactoring operation.
Use standard testing tools: JUnit, TestNG, etc.
Current Java IDE provide refactoring operations: Eclipse, Netbeans, IntelliJ IDEA
Refactoring Browser, Lint.
Bicycle Repair Man, pycheck.
Eclipse, IntelliJ Idea, JFactor, XRefactory, JBuilder, RefactorIt, JRefactory, Transmogrify, JafaRefactor, CodeGuide, jLint.
SlickEdit, Ref++, Xrefactory.
Ruby Refactoring
Introduction
Refactoring Operations
When to Refactor
Why Refactor
Refactor to Improve Extensibility
Refactor to Improve Maintainability
Integrate Refactoring to Software Development Process
Automatization
Conclusion
Evolutionary Software Development
Refactoring operations
Ways of integrating refactoring into your process
PhD Thesis from William Opdyke, Don Roberts, and John Brant.
Martin Fowler’s book and website
Several slides and examples are based on a John Brant and Don Roberts presentation "Refactoring Techniques and Tools" at Smalltalk Solutions '99.