Refactoring & Code Quality

Refactoring Catalog: Core Mechanics

Refactoring is the disciplined technique of restructuring code without changing its observable behavior, in small, independently verifiable steps. A handful of mechanical moves — Extract, Inline, Rename, Move — cover the large majority of real refactoring work.
  • Extract Method/Function: pull a cohesive fragment out into a well-named method, replacing it with a call
  • Extract Variable: name an expression so the code reads as intent rather than arithmetic
  • Inline Method/Variable: the reverse move — when the indirection adds no clarity, fold it back in
  • Rename: the highest-leverage, lowest-risk refactoring there is — a name is documentation that never goes stale if it stays accurate
  • Move Method/Field: relocate behavior or data to the class it is most cohesive with (the fix for Feature Envy, see Code Smells)
  • Every refactoring is reversible — Extract has an Inline, Move has a Move-back — which is what makes "try it and see" a legitimate way to explore a design
Core refactorings and their intent
RefactoringIntent
Extract MethodTurn an unnamed fragment into a named, reusable, independently testable unit
Extract VariableReplace an opaque expression with a name that explains what it means
Inline Method / VariableRemove indirection that has stopped paying for itself
RenameMake the name match what the thing actually is, now
Move Method / FieldPut behavior or data next to what it is most cohesive with
Extract Method, before and after
// Before: one method, two responsibilities buried inside it.
void printInvoice(Invoice invoice) {
    double total = 0;
    for (LineItem item : invoice.getItems()) {
        total += item.getPrice() * item.getQuantity();
    }
    System.out.println("Total: 
quot;
+ total); for (LineItem item : invoice.getItems()) { System.out.println(item.getName() + " x" + item.getQuantity()); } } // After: each cohesive fragment gets a name. void printInvoice(Invoice invoice) { System.out.println("Total:
quot;
+ calculateTotal(invoice)); printLineItems(invoice); } double calculateTotal(Invoice invoice) { /* the sum, extracted */ } void printLineItems(Invoice invoice) { /* the loop, extracted */ }
Sources
  • Refactoring: Improving the Design of Existing Code (2nd ed.)Ch. 6, 7 — A First Set of Refactorings; Encapsulation