Why Refactoring Matters: Principles, Timing, and Practical Techniques
Refactoring improves code understandability and reduces maintenance costs by reorganizing internal structure without changing behavior, and this guide explains its purpose, timing, principles, common code smells, measurement metrics, and practical techniques across data, statement, subroutine, class, and system levels.
Introduction
Recently I saw questions like “Is code refactoring meaningful?” and “Any good methodology for refactoring?” I have been interested in refactoring since 2013, studying theories and practicing them, and now I share the principles, concepts and techniques.
What is Refactoring?
Refactoring is an adjustment of the internal structure of software aimed at improving understandability and reducing modification cost without changing external behavior.
Why Refactor?
1. Improve software design
As Martin Fowler wrote, early refactoring clears “the dirt on the window,” allowing us to see higher‑level design issues that would otherwise remain hidden.
Short‑term code changes for immediate needs often degrade structure, making the code hard to understand and maintain.
Refactoring helps reorganize code, making the structure clear and improving design.
2. Increase code quality and readability
Readable code is easier to maintain and extend; code is documentation first for people, then for machines.
3. Early bug detection
Refactoring acts as a code‑review process that makes problems easier to spot.
It is a good software development habit.
4. Faster development
Better design and code quality accelerate development; fixing design defects later costs more time.
Maintenance cost far exceeds development cost.
When to Refactor?
Add new feature together with refactoring
To add a feature, developers must first understand existing code.
If existing code hinders adding features, refactor.
Fix bugs together with refactoring
Bug fixing requires understanding current code.
Logical difficulties during bug fixing can be eased by refactoring.
Refactor during code review
Code review can verify readability and understandability.
Start refactoring when you smell “bad code”
When Not to Refactor?
If the code is extremely messy or the design is completely wrong, rewrite instead of refactor.
When a deadline is imminent.
Never make last‑minute changes; postpone refactoring but do not ignore it.
If refactoring would significantly affect the deadline, treat it as a separate task.
Refactoring Principles
Two hats: Refactor vs Add Feature
When adding a feature, avoid modifying existing code.
When refactoring, focus on improving structure without adding features.
The two hats can be switched as needed.
Refactoring and Design
Refactoring assists design evolution when requirements change, allowing existing implementation to adapt without a complete rewrite.
Refactoring and Performance
Refactoring does not guarantee faster performance, but it makes performance optimization easier by providing a clean code base.
A well‑structured codebase gives time for performance tuning and finer‑grained measurement.
Refactoring Taboo
Reference “The Seven Sins of Refactoring”
Refactoring has evolved over a decade and is a beloved practice in extreme programming, yet it can go wrong if misapplied.
1. Refactor without understanding the goal
Unclear objectives lead to wasted effort on personal preferences rather than solving real problems.
2. Not knowing when refactoring is done
Define measurable criteria (e.g., reduce duplicated lines, lower complexity) before starting.
3. Violent refactoring without method
Blindly cutting, copying, deleting code often introduces bugs; use proven refactoring techniques such as method extraction, bridging, etc.
4. No strategy, perfectionism
Small incremental steps with testing are preferred; avoid large‑scale changes that risk project timelines.
5. Uncertain results
Simple code‑level refactoring may not need verification, but module‑level changes require validation.
6. Ignoring the “seven sins”
Metrics to evaluate refactoring: quantity (lines of code), quality (complexity, coupling, readability, architectural dependencies), cost (time), and return (support future features, resolve design constraints).
7. Not communicating with the team
Assess risks, impact on other modules, and discuss benefits and drawbacks with stakeholders.
Refactoring Metrics
Quantity: lines of code; Quality: complexity, coupling, readability, architectural dependencies; Cost: time spent; Return: faster feature stacking, solving design‑related constraints.
Code Smells
Common smells include duplicated code, long methods, deep nesting, low class cohesion, inconsistent abstraction, many parameters, parallel modifications across classes, reliance on global variables, and more.
Duplicated code.
Long sub‑routines.
Deep or long loops.
Poor class cohesion.
Inconsistent abstraction in class interfaces.
Too many parameters.
Scattered modifications across classes.
Parallel changes in inheritance hierarchies.
Parallel changes in multiple case statements.
Data items grouped without proper class.
Member functions using other classes more than own.
Overuse of primitive types.
Classes that do nothing.
Data‑flow “train‑wreck” code.
Middle‑man objects that do nothing.
Classes overly coupled with others.
Poorly named sub‑routines.
Public data members.
Derived classes using only a small part of base class.
Using comments to hide bad code.
Use of global variables.
Setup/teardown code surrounding sub‑routines.
Code that seems to be needed only in the future
Refactoring Techniques
Below is a brief summary of techniques grouped by level.
Data‑level Refactoring
Replace magic numbers with named constants.
Rename variables with clearer, more informative names.
Inline expressions.
Replace expressions with functions.
Introduce temporary variables.
Split multi‑purpose variables into single‑purpose ones.
Use local variables instead of parameters for local use.
Convert primitive types to classes.
Replace type codes with classes or enums.
Replace arrays with objects.
Encapsulate collections.
Replace traditional records with data classes.
Statement‑level Refactoring
Decompose boolean expressions.
Extract named boolean functions.
Merge duplicated code in different branches.
Use break or return instead of loop control variables.
Exit early from nested if‑then‑else when result is known.
Replace conditionals with polymorphism.
Introduce and use null objects.
Subroutine‑level Refactoring
Extract subroutines.
Inline subroutines.
Convert long subroutines into classes.
Replace complex algorithms with simpler ones.
Add or remove parameters.
Separate query operations from modification operations.
Merge similar subroutines and differentiate with parameters.
Use parameters to vary subroutine behavior.
Pass whole objects instead of specific members.
Pass specific members instead of whole objects.
Encapsulate down‑casting operations.
Class‑level Refactoring
Change value objects to reference objects.
Change reference objects to value objects.
Replace virtual functions with data initialization.
Move member functions or data.
Generate derived classes from specific code.
Merge similar code into a base class.
Class Interface Refactoring
Move a member subroutine to another class.
Split a class into two.
Delete a class.
Hide delegation relationships.
Remove middle‑man.
Replace inheritance with delegation.
Replace delegation with inheritance.
Introduce external subroutines.
Introduce extension classes.
Expose member variables.
Remove setters for immutable members.
Hide unused member functions.
Encapsulate unused member functions.
Merge base and derived classes when implementations are similar.
System‑level Refactoring
Create explicit index sources for uncontrolled data.
Change unidirectional class relationships to bidirectional.
Change bidirectional relationships to unidirectional.
Use factory functions instead of simple constructors.
Replace error codes with exceptions.
Basic Tips
Take small steps, test frequently (unit tests are ideal).
Leverage smart IDE tools (e.g., VSCode to extract functions, Android Studio).
Conclusion
Refactoring should be a core skill for developers. Good programmers avoid low‑quality code and make refactoring a regular part of development, writing tests to ensure behavior stays unchanged while gradually improving the code base. Not every short‑lived feature needs refactoring, but core business code benefits greatly.
References
https://insights.thoughtworks.cn/refactoring/
https://zhuanlan.zhihu.com/p/32931437
https://www.cnblogs.com/levenyes/p/9903156.html
https://www.jianshu.com/p/f667ea3e4a11
Reference books and knowledge points are illustrated below
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
