Refactoring Principles, Code Smells, and Refactoring Techniques
This article explains refactoring as a disciplined way to improve software structure without altering behavior, outlines common code smells, and presents a comprehensive set of refactoring techniques—including extracting functions, moving features, simplifying conditionals, and reorganizing data—illustrated with Java code examples.
Refactoring is a systematic approach to adjusting a software system’s internal structure while preserving its observable behavior, with the goals of improving readability, reducing maintenance cost, and facilitating future changes.
Refactoring Principles
1. What is refactoring? It is a set of transformations that restructure code without changing its external functionality. 2. Why refactor? To prevent design decay, uncover bugs, and increase development speed by keeping the code clean and understandable. 3. When to refactor? Refactoring should be done continuously, not as a separate scheduled task; the “three‑time rule” suggests refactoring when you encounter the same code for the third time.
Common Code Smells
Examples include duplicated code, overly long classes or methods, large parameter lists, divergent changes, shotgun surgery, excessive coupling, data clumps, primitive obsession, switch statements, redundant classes, and over‑commented code. Each smell indicates a specific structural problem that can be addressed with targeted refactorings.
Reorganizing Functions
Techniques such as Extract Method (create a well‑named new function for a code fragment), Inline Method (replace a simple method call with its body), and Inline Temporary Variable (replace a temporary variable with its expression) help simplify and clarify logic.
Example of extracting a temporary variable:
double basePrice = quantity * timePrice;
if (basePrice > 1000) {
return basePrice * 9.5;
} else {
return basePrice * 0.98;
}After applying Extract Method and Replace Temp with Query :
if (basePrice() > 1000) {
return basePrice() * 9.5;
} else {
return basePrice() * 0.98;
}
private double basePrice() {
return quantity * timePrice;
}Moving Features Between Objects
When a class takes on too many responsibilities, Extract Class can split responsibilities into a new class. Conversely, if a class is too lightweight, Inline Class can merge it into another. Move Method and Move Field relocate behavior or data to the class that uses them most.
Example of moving a method:
public int discount(int inputVal, int quantity, int yearToDate) {
int result = inputVal;
if (inputVal > 50) result -= 2;
return result;
}After moving the calculation to a helper method:
public int discount(int inputVal, int quantity, int yearToDate) {
int result = inputVal;
if (inputVal > 50) result -= 2;
return result;
}
private int adjustInput(int inputVal) {
if (inputVal > 50) return inputVal - 2;
return inputVal;
}Reorganizing Data
Encapsulate public fields, replace primitive data with value objects, convert arrays to objects, and introduce constants to eliminate magic numbers. For instance, replace direct field access with getter/setter methods, or turn a range of two ints into a dedicated Range class.
Simplifying Conditionals
Techniques include extracting complex boolean expressions into well‑named methods, merging duplicate branches, removing control flags, and replacing conditionals with polymorphism (e.g., using subclass overrides instead of if (type == …) ).
Simplifying Function Calls
Rename ambiguous functions, add or remove parameters, split functions into query and command parts, replace parameter‑driven logic with separate functions, and introduce parameter objects to group related arguments.
Handling Generalization
Move common fields or methods up to a superclass, extract interfaces for shared behavior, collapse unnecessary inheritance hierarchies, and replace inheritance with delegation when appropriate.
Recommended Reading
JAVA Online Fault Diagnosis Guide
Three MySQL Large‑Table Optimization Strategies
RocketMQ Message Loss and Solutions
Optimizing Excel Import of 100,000 Rows
ElasticSearch Search Principles Illustrated with Diagrams
If you found this guide useful, please give it a like and share your feedback.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.