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
| Refactoring | Intent |
|---|---|
| Extract Method | Turn an unnamed fragment into a named, reusable, independently testable unit |
| Extract Variable | Replace an opaque expression with a name that explains what it means |
| Inline Method / Variable | Remove indirection that has stopped paying for itself |
| Rename | Make the name match what the thing actually is, now |
| Move Method / Field | Put behavior or data next to what it is most cohesive with |
// 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 */ }