Refactoring: Improving the Design of Existing Code
by Martin Fowler, Kent Beck (Contributor), John Brant (Contributor), William
Opdyke, don Roberts
For all the people which doesn’t have money to buy a good book
Another stupid release 2002J
Your class library works, but could it be better? Refactoring: Improving the Design of
Existing Code shows how refactoring can make object-oriented code simpler and easier
to maintain. Today refactoring requires considerable design know-how, but once tools
become available, all programmers should be able to improve their code using refactoring
techniques.
Besides an introduction to refactoring, this handbook provides a catalog of dozens of tips
for improving code. The best thing about Refactoring is its remarkably clear presentation,
along with excellent nuts-and-bolts advice, from object expert Martin Fowler. The author
is also an authority on software patterns and UML, and this experience helps make this a
better book, one that should be immediately accessible to any intermediate or advanced
object-oriented developer. (Just like patterns, each refactoring tip is presented with a
simple name, a "motivation," and examples using Java and UML.)
Early chapters stress the importance of testing in successful refactoring. (When you
improve code, you have to test to verify that it still works.) After the discussion on how
to detect the "smell" of bad code, readers get to the heart of the book, its catalog of over
70 "refactorings"--tips for better and simpler class design. Each tip is illustrated with
"before" and "after" code, along with an explanation. Later chapters provide a quick look
at refactoring research.
Like software patterns, refactoring may be an idea whose time has come. This
groundbreaking title will surely help bring refactoring to the programming mainstream.
With its clear advice on a hot new topic, Refactoring is sure to be essential reading for
anyone who writes or maintains object-oriented software. --Richard Dragan
Topics Covered: Refactoring, improving software code, redesign, design tips, patterns,
unit testing, refactoring research, and tools.
Book News, Inc.
A guide to refactoring, the process of changing a software system so that it does not alter
the external behavior of the code yet improves its internal structure, for professional
programmers. Early chapters cover general principles, rationales, examples, and testing.
The heart of the book is a catalog of refactorings, organized in chapters on composing
methods, moving features between objects, organizing data, simplifying conditional
expressions, and dealing with generalizations
2
Foreword........................................................................................................................ 6
Preface........................................................................................................................... 8
What Is Refactoring? ............................................................................................... 9
What's in This Book? ............................................................................................... 9
Who Should Read This Book? ............................................................................. 10
Building on the Foundations Laid by Others ...................................................... 10
Acknowledgments .................................................................................................. 11
Chapter 1. Refactoring, a First Example ................................................................ 13
The Starting Point................................................................................................... 13
The First Step in Refactoring ................................................................................ 17
Decomposing and Redistributing the Statement Method ................................ 18
Replacing the Conditional Logic on Price Code with Polymorphism ............. 35
Final Thoughts ........................................................................................................ 44
Chapter 2. Principles in Refactoring ........................................................................ 46
Defining Refactoring .............................................................................................. 46
Why Should You Refactor? .................................................................................. 47
Refactoring Helps You Find Bugs ....................................................................... 48
When Should You Refactor?................................................................................ 49
What Do I Tell My Manager?................................................................................ 52
Problems with Refactoring .................................................................................... 54
Refactoring and Design......................................................................................... 57
Refactoring and Performance .............................................................................. 59
Where Did Refactoring Come From?.................................................................. 60
Chapter 3. Bad Smells in Code................................................................................ 63
Duplicated Code ..................................................................................................... 63
Long Method ........................................................................................................... 64
Large Class ............................................................................................................. 65
Long Parameter List............................................................................................... 65
Divergent Change .................................................................................................. 66
Shotgun Surgery..................................................................................................... 66
Feature Envy........................................................................................................... 66
Data Clumps ........................................................................................................... 67
Primitive Obsession ............................................................................................... 67
Switch Statements ................................................................................................. 68
Parallel Inheritance Hierarchies ........................................................................... 68
Lazy Class ............................................................................................................... 68
Speculative Generality........................................................................................... 68
Temporary Field ..................................................................................................... 69
Message Chains ..................................................................................................... 69
Middle Man.............................................................................................................. 69
Inappropriate Intimacy ........................................................................................... 70
Alternative Classes with Different Interfaces ..................................................... 70
Incomplete Library Class....................................................................................... 70
Data Class ............................................................................................................... 70
Refused Bequest.................................................................................................... 71
3
Comments ............................................................................................................... 71
Chapter 4. Building Tests.......................................................................................... 73
The Value of Self-testing Code ............................................................................ 73
The JUnit Testing Framework .............................................................................. 74
Adding More Tests ................................................................................................. 80
Chapter 5. Toward a Catalog of Refactorings ....................................................... 85
Format of the Refactorings ................................................................................... 85
Finding References................................................................................................ 86
How Mature Are These Refactorings?................................................................ 87
Chapter 6. Composing Methods .............................................................................. 89
Extract Method........................................................................................................ 89
Inline Method........................................................................................................... 95
Inline Temp.............................................................................................................. 96
Replace Temp with Query .................................................................................... 97
Introduce Explaining Variable............................................................................. 101
Split Temporary Variable ..................................................................................... 104
Remove Assignments to Parameters ............................................................... 107
Replace Method with Method Object ................................................................ 110
Substitute Algorithm ............................................................................................. 113
Chapter 7. Moving Features Between Objects.................................................... 115
Move Method ........................................................................................................ 115
Move Field ............................................................................................................. 119
Extract Class ......................................................................................................... 122
Inline Class ............................................................................................................ 125
Hide Delegate ....................................................................................................... 127
Remove Middle Man............................................................................................ 130
Introduce Foreign Method................................................................................... 131
Introduce Local Extension................................................................................... 133
Chapter 8. Organizing Data .................................................................................... 138
Self Encapsulate Field ......................................................................................... 138
Replace Data Value with Object ........................................................................ 141
Change Value to Reference ............................................................................... 144
Change Reference to Value ............................................................................... 148
Replace Array with Object .................................................................................. 150
Duplicate Observed Data .................................................................................... 153
Change Unidirectional Association to Bidirectional ........................................ 159
Change Bidirectional Association to Unidirectional ........................................ 162
Replace Magic Number with Symbolic Constant ............................................ 166
Encapsulate Field ................................................................................................. 167
Encapsulate Collection........................................................................................ 168
Replace Record with Data Class ....................................................................... 175
Replace Type Code with Class .......................................................................... 176
Replace Type Code with Subclasses ............................................................... 181
Replace Type Code with State/Strategy........................................................... 184
Replace Subclass with Fields............................................................................. 188
Chapter 9. Simplifying Conditional Expressions ................................................. 192
4
Decompose Conditional ...................................................................................... 192
Consolidate Conditional Expression ................................................................. 194
Consolidate Duplicate Conditional Fragments ................................................ 196
Remove Control Flag ........................................................................................... 197
Replace Nested Conditional with Guard Clauses ........................................... 201
Replace Conditional with Polymorphism .......................................................... 205
Introduce Null Object ........................................................................................... 209
Introduce Assertion .............................................................................................. 216
Chapter 10. Making Method Calls Simpler........................................................... 220
Rename Method ................................................................................................... 221
Add Parameter...................................................................................................... 222
Remove Parameter .............................................................................................. 223
Separate Query from Modifier ............................................................................ 225
Parameterize Method .......................................................................................... 228
Replace Parameter with Explicit Methods........................................................ 230
Preserve Whole Object ....................................................................................... 232
Replace Parameter with Method ....................................................................... 235
Introduce Parameter Object ............................................................................... 238
Remove Setting Method...................................................................................... 242
Hide Method .......................................................................................................... 245
Replace Constructor with Factory Method ....................................................... 246
Encapsulate Downcast........................................................................................ 249
Replace Error Code with Exception .................................................................. 251
Replace Exception with Test .............................................................................. 255
Chapter 11. Dealing with Generalization.............................................................. 259
Pull Up Field .......................................................................................................... 259
Pull Up Method ..................................................................................................... 260
Pull Up Constructor Body.................................................................................... 263
Push Down Method.............................................................................................. 266
Push Down Field .................................................................................................. 266
Extract Subclass ................................................................................................... 267
Extract Superclass ............................................................................................... 272
Extract Interface ................................................................................................... 277
Collapse Hierarchy............................................................................................... 279
Form Template Method ....................................................................................... 280
Replace Inheritance with Delegation................................................................. 287
Replace Delegation with Inheritance................................................................. 289
Chapter 12. Big Refactorings ................................................................................. 293
Tease Apart Inheritance ...................................................................................... 294
Convert Procedural Design to Objects ............................................................. 300
Separate Domain from Presentation................................................................. 302
Extract Hierarchy.................................................................................................. 306
Chapter 13. Refactoring, Reuse, and Reality...................................................... 311
A Reality Check .................................................................................................... 311
Why Are Developers Reluctant to Refactor Their Programs? ...................... 312
A Reality Check (Revisited) ................................................................................ 323
5
Resources and References for Refactoring ..................................................... 323
Implications Regarding Software Reuse and Technology Transfer............. 324
A Final Note........................................................................................................... 325
Endnotes................................................................................................................ 325
Chapter 14. Refactoring Tools ............................................................................... 328
Refactoring with a Tool........................................................................................ 328
Technical Criteria for a Refactoring Tool.......................................................... 329
Practical Criteria for a Refactoring Tool............................................................ 331
Wrap Up ................................................................................................................. 332
Chapter 15. Putting It All Together ........................................................................ 333
Bibliography........................................................................................................... 336
References ................................................................................................................ 336
Foreword
"Refactoring" was conceived in Smalltalk circles, but it wasn't long before it found its way into
other programming language camps. Because refactoring is integral to framework development,
the term comes up quickly when "frameworkers" talk about their craft. It comes up when they
refine their class hierarchies and when they rave about how many lines of code they were able to
delete. Frameworkers know that a framework won't be right the first time around—it must evolve
as they gain experience. They also know that the code will be read and modified more frequently
than it will be written. The key to keeping code readable and modifiable is refactoring—for
frameworks, in particular, but also for software in general.
So, what's the problem? Simply this: Refactoring is risky. It requires changes to working code that
can introduce subtle bugs. Refactoring, if not done properly, can set you back days, even weeks.
And refactoring becomes riskier when practiced informally or ad hoc. You start digging in the
code. Soon you discover new opportunities for change, and you dig deeper. The more you dig,
the more stuff you turn up…and the more changes you make. Eventually you dig yourself into a
hole you can't get out of. To avoid digging your own grave, refactoring must be done
systematically. When my coauthors and I wrote Design Patterns, we mentioned that design
patterns provide targets for refactorings. However, identifying the target is only one part of the
problem; transforming your code so that you get there is another challenge.
Martin Fowler and the contributing authors make an invaluable contribution to object-oriented
software development by shedding light on the refactoring process. This book explains the
principles and best practices of refactoring, and points out when and where you should start
digging in your code to improve it. At the book's core is a comprehensive catalog of refactorings.
Each refactoring describes the motivation and mechanics of a proven code transformation. Some
of the refactorings, such as Extract Method or Move Field, may seem obvious.
But don't be fooled. Understanding the mechanics of such refactorings is the key to refactoring in
a disciplined way. The refactorings in this book will help you change your code one small step at
a time, thus reducing the risks of evolving your design. You will quickly add these refactorings
and their names to your development vocabulary.
My first experience with disciplined, "one step at a time" refactoring was when I was pair-
programming at 30,000 feet with Kent Beck. He made sure that we applied refactorings from this
book's catalog one step at a time. I was amazed at how well this practice worked. Not only did my
confidence in the resulting code increase, I also felt less stressed. I highly recommend you try
these refactorings: You and your code will feel much better for it.
6
—Erich Gamma
Object Technology International, Inc.
7
Preface
Once upon a time, a consultant made a visit to a development project. The consultant looked at
some of the code that had been written; there was a class hierarchy at the center of the system.
As he wandered through the hierarchy, the consultant saw that it was rather messy. The higher-
level classes made certain assumptions about how the classes would work, assumptions that
were embodied in inherited code. That code didn't suit all the subclasses, however, and was
overridden quite heavily. If the superclass had been modified a little, then much less overriding
would have been necessary. In other places some of the intention of the superclass had not been
properly understood, and behavior present in the superclass was duplicated. In yet other places
several subclasses did the same thing with code that could clearly be moved up the hierarchy.
The consultant recommended to the project management that the code be looked at and cleaned
up, but the project management didn't seem enthusiastic. The code seemed to work and there
were considerable schedule pressures. The managers said they would get around to it at some
later point.
The consultant had also shown the programmers who had worked on the hierarchy what was
going on. The programmers were keen and saw the problem. They knew that it wasn't really their
fault; sometimes a new pair of eyes are needed to spot the problem. So the programmers spent a
day or two cleaning up the hierarchy. When they were finished, the programmers had removed
half the code in the hierarchy without reducing its functionality. They were pleased with the result
and found that it became quicker and easier both to add new classes to the hierarchy and to use
the classes in the rest of the system.
The project management was not pleased. Schedules were tight and there was a lot of work to
do. These two programmers had spent two days doing work that had done nothing to add the
many features the system had to deliver in a few months time. The old code had worked just fine.
So the design was a bit more "pure" a bit more "clean." The project had to ship code that worked,
not code that would please an academic. The consultant suggested that this cleaning up be done
on other central parts of the system. Such an activity might halt the project for a week or two. All
this activity was devoted to making the code look better, not to making it do anything that it didn't
already do.
How do you feel about this story? Do you think the consultant was right to suggest further clean
up? Or do you follow that old engineering adage, "if it works, don't fix it"?
I must admit to some bias here. I was that consultant. Six months later the project failed, in large
part because the code was too complex to debug or to tune to acceptable performance.
The consultant Kent Beck was brought in to restart the project, an exercise that involved rewriting
almost the whole system from scratch. He did several things differently, but one of the most
important was to insist on continuous cleaning up of the code using refactoring. The success of
this project, and role refactoring played in this success, is what inspired me to write this book, so
that I could pass on the knowledge that Kent and others have learned in using refactoring to
improve the quality of software.
8