REFACTOR
WHAT IS REFACTORING?
Refactoring consists in modifying software to improve its readibility, maintainability and extensibility without changing what it actually does
noun: a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior
verb: to restructure software by applying a series of refactorings without changing its observable behavior
MARTIN FOWLER DEFINITION (AUTHOR OF REFACTORING.COM)

Refactoring isn't another word for cleaning up code - it specifically defines one technique for improving the health of a code-base. I use "restructuring" as a more general term for reorganizing code that may incorporate other techniques.
WHY REFACTOR?

It’s like I want to go 100 miles east but instead of just traipsing through the woods, I’m going to drive 20 miles north to the highway and then I’m going to go 100 miles east at three times the speed I could have if I just went straight there. When people are pushing you to just go straight there, sometimes you need to say, “Wait, I need to check the map and find the quickest route.” The preparatory refactoring does that for me.
Keep the external quality but improve the internal quality
Keep the external quality but improve the internal quality
Refactoring involves changing things, hence it can (and so it will!) introduce problems.
Be ready for them, take the opportunity to automate tests, do it in small incremental steps, etc.
Refactoring Risks



Keep the external quality but improve the internal quality
EXAMPLES????
Keep the external quality but improve the internal quality
Extract code to new/other method/classes
Move methods
Rename methods/objects/attributes
add attributes to classes/methods
Change Classes Structure
EXAMPLES
Example 1 - Consolidate Conditional Expression
Example 1 - Consolidate Conditional Expression
Example 2 - Decompose Conditionals
Example 3
Move a method from class A to class B if uses/is being used by more features in class B

Example 4
Introduce Null Object
Imagine in your software you are always checking if instances of an object are null:
Customer c = findCustomer(...);
...
if (customer == null) {
name = "occupant";
} else {
name = customer.getName();
}
...
if (customer == null) {
...
}
Duplicating code, makes it more difficult to be maintained, more complex, more difficult to be understood
Example 4
Introduce Null Object
public class NullCustomer extends Customer {
public String getName() {
return “occupant”
}
------------------------------------------------------------
Customer c = findCustomer()
name = c.getName()
Example 5
Switch Statements
- switch statements are very rare in properly designed object-oriented code
- Therefore, a switch statement is a simple and easily detected “bad smell”
- Of course, not all uses of switch are bad
- Switch statement should not be used to distinguish between various kinds of objects.
- There are several well-defined refactorings for this case.
- The simplest is the creation of subclasses
Example 5
Switch Statements
class Animal {
final int MAMMAL = 0, BIRD = 1, REPTILE = 2;
int myKind; // set in constructor
...
String getSkin() {
switch (myKind) {
case MAMMAL: return "hair";
case BIRD: return "feathers";
case REPTILE: return "scales";
default: return "integument";
}
}
}
Example 5
Switch Statements
class Animal {
final int MAMMAL = 0, BIRD = 1, REPTILE = 2;
int myKind; // set in constructor
...
String getSkin() {
switch (myKind) {
case MAMMAL: return "hair";
case BIRD: return "feathers";
case REPTILE: return "scales";
default: return "integument";
}
}
}
class Animal {
String getSkin() { return "integument"; }
}
class Mammal extends Animal {
String getSkin() { return "hair"; }
}
class Bird extends Animal {
String getSkin() { return "feathers"; }
}
class Reptile extends Animal {
String getSkin() { return "scales"; }
}
- Adding a new animal type, such as Amphibian, does not require revising and recompiling existing code - Mammals, birds, and reptiles are likely to differ in other ways, and we’ve already separated them out (so we won’t need more switch statements) - We’ve gotten rid of the flags we needed to tell one kind of animal from another - Basically, we’re now using Objects the way they were meant to be used
Advantages:
A lot of examples
Identifying aspects to refactor
"Bad Smells"
Bad Smells: is a term coined by Martin Fowler

Developing Stinky Code
BAD SMELLS - I
- DUPLICATED CODE: Bad because you need to mantain the code as many times as it's duplicated
- LONG METHOD: Bad because they are more difficult to be understood, more error prone, etc.
- LARGE CLASS: If a class is doing too much, OO is useless.
- LONG PARAMETER LIST: Hard to understand
- DATA CLASS: Class without behaviour implementation
BAD SMELLS - II
- DIVERGENT CHANGES / SHOTGUN SURGERY: Two sides of the coin:
- No matter what you need to change in your code, a class must be always modified.
- One change/new feature requires changing a lot of things in different places.
- FEATURE ENVY: Method is more interested in a class than in its own class.
- REPEATED SWITCH STATEMENTS: Symptom of not using properly OO programming
https://sourcemaking.com/refactoring/smells
Bad Smells Video - I

Bad Smells Video - II

Develop your nose
https://sourcemaking.com/refactoring/smells
Choose one group and investigate some possible bad-smells
A "complete" example
5.D.1 and 5.D.2
DETECTING BAD SMELLS
HOW CAN YOU DETECT THEM?
REMEMBER THIS IS ABOUT INTERNAL QUALITY!
CODE REVIEWS
CODE ANALYSIS
DEFECT ANALYSIS
STATIC ANALYSIS TOOLS CAN HELP US
(EXAMPLE: LINTERS)
MAKING IT SMELL WELL
There are a lot patterns/catalogs
Have a look at them, but the most important thing is to use common sense
... and practice a lot!
... and tools can also help us
REFACTOR
By Daniel Coloma
REFACTOR
- 750