Refactoring

What

The first version of the code you write may not be of production quality. It is OK to first concentrate on making the code work, rather than worry over the quality of the code, as long as you improve the quality later. This process of improving a program's internal structure in small steps without modifying its external behavior is called refactoring.

  • Refactoring is not rewriting: Discarding poorly-written code entirely and re-writing it from scratch is not refactoring because refactoring needs to be done in small steps.
  • Refactoring is not bug fixing: By definition, refactoring is different from bug fixing or any other modifications that alter the external behavior (e.g. adding a feature) of the component in concern.

💡 Improving code structure can have many secondary benefits: e.g.

  • hidden bugs become easier to spot
  • improve performance (sometimes, simpler code runs faster than complex code because simpler code is easier for the compiler to optimize).

Given below are two common refactorings (taken from refactoring-catalog ).

http://refactoring.com/catalog/ - This is a list of common refactorings, maintained by Martin Fowler, a leading authority on refactoring. He is also the author of the ‘bestseller’ on refactoring: Refactoring: Improving the Design of Existing Code

Refactoring Name: Consolidate Duplicate Conditional Fragments

Situation: The same fragment of code is in all branches of a conditional expression.

Method: Move it outside of the expression.

Example:

if (isSpecialDeal()) {
    total = price * 0.95;
    send();
} else {
    total = price * 0.98;
    send();
}

⤵️

if (isSpecialDeal()){
    total = price * 0.95;
} else {
    total = price * 0.98;
}
send();

Refactoring Name: Extract Method

Situation: You have a code fragment that can be grouped together.

Method: Turn the fragment into a method whose name explains the purpose of the method.

Example:

void printOwing() {
    printBanner();

    //print details
    System.out.println("name:	" + name);
    System.out.println("amount	" + getOutstanding());
}

⤵️

void printOwing() {
    printBanner();
    printDetails(getOutstanding());
}

void printDetails (double outstanding) {
    System.out.println("name:	" + name);
    System.out.println("amount	" + outstanding);
}

💡 Some IDEs have built in support for basic refactorings such as automatically renaming a variable/method/class in all places it has been used.

Important: Refactoring, even if done with the aid of an IDE, may still result in regressions. Therefore, each small refactoring should be followed by regression testing.

How

Given below are some more commonly used refactorings. A more comprehensive list is available at refactoring-catalog .

http://refactoring.com/catalog/ - This is a list of common refactorings, maintained by Martin Fowler, a leading authority on refactoring. He is also the author of the ‘bestseller’ on refactoring: Refactoring: Improving the Design of Existing Code

  1. Consolidate Conditional Expression
  2. Decompose Conditional
  3. Inline Method
  4. Remove Double Negative
  5. Replace Magic Number with Symbolic Constant
  6. Replace Nested Conditional with Guard Clauses
  7. Replace Parameter with Explicit Methods
  8. Reverse Conditional
  9. Split Loop
  10. Split Temporary Variable

When

We know that it is important to refactor frequently so as to avoid the accumulation of ‘messy’ code which might get out of control. But how much refactoring is too much refactoring? It is too much refactoring when the benefits no longer justify the cost. The costs and the benefits depend on the context. That is why some refactorings are ‘opposites’ of each other (e.g. extract method vs inline method).