Review: Refactoring to Patterns
Refactoring code and design patterns are becoming more common in programming, so why not have a solid understanding of how to refactor existing code into patterns?
When I started coding in a corporate environment, I never knew the term "to refactor code" until 2004. I was more concerned about the AJAX movement at the time.
Now, as I've mentioned before with the Top 10 Books every .NET Developer Should Own, design patterns and refactoring books are becoming awesome guides that developers can take and learn from seasoned developers and architects who have experienced every manner of code known to man and write about their thought process on converting that code into something better.
Refactoring to Patterns is one of those books.
Refactoring to Patterns (2004) from Joshua Kerievsky takes the process of refactoring a piece of code and turning them into a proven and tested design pattern.
If you've read the Design Patterns: Elements of Reusable Object-Oriented Software from the original gang of four (or Design Patterns in C# for you .NET developers) and also read the Refactoring: Improving the Design of Existing Code book, Refactoring to Patterns expands on this knowledge.
If these were classes, the Design Patterns book would be 101, the Refactoring book would be 102, and Refactoring to Patterns would be considered a 201 class building off of your design patterns and refactoring knowledge.
But enough about that. Let's get into the review.
The book is broken into 11 chapters:
- Why I Wrote This Book
- Code Smells
- A Catalog of Refactorings to Patterns
The last seven serve as reference material once you are done with the book. They have a total of 27 code refactorings and they are based on real-world code.
If you've read the Refactoring book, then you already have a good understanding of what Chapter 2 is like. It discusses why we are motivated to refactor code and some of the refactoring tools available.
As you probably have guessed, Chapter 3 gives an overview of 'what is a design pattern" and some great and not-so-great ways to implement design patterns. If you've read either Design Pattern books above, you could skip this chapter as well (unless you want a refresher on patterns).
Chapter 4 happens to be my favorite because it teaches you how to identify a piece of code that needs refactored. These pieces of code are called Code Smells. Code smells are in everyone's code, they are just masked in different ways. This chapter goes through the different types of code smells:
- Duplicated Code
- Long Method
- Conditional Complexity
- Primitive Obsession
- Indecent Exposure
- Solution Sprawl
- Alternative Classes with Different Interfaces
- Lazy Class
- Large Class
- Switch Statements
- Combinatorial Explosion
- Oddball Solution
Chapter 5 talks about how the rest of the book is formatted for each refactoring.
Now we get to the meat of the book.
While I won't go into every single refactoring, I will list all of them in each chapter.
The catalog from here on gives an introduction on how to approach each refactoring. For example, in Chapter 6, they discuss a possible scenario when determining whether to use the Creation refactorings or not.
"If there are too many constructors on a class, clients will have a difficult time knowing which constructor to call. One solution is to the reduce the number of constructors by applying such refactorings as Extract Class or Extract Subclass. If that isn't possible or useful, you can clarify the intention of the constructors by applying Replace Constructor with Creation Methods."
This type of introduction gets into the head of the developer and walks them through possible alternatives to rewriting their code.
Another reason I love the Signature Series.
Chapter 6 talks about the Creation of classes and their relevant refactorings.
- Replace Constructors with Creation Methods
- Move Creation Knowledge to Factory
- Encapsulate Classes with Factory
- Introduce Polymorphic Creation with Factory Method
- Encapsulate Composite with Builder
- Inline Singleton
The Simplification chapter (Chapter 7) takes complex methods and evaluates whether they can be simplified or not using the following refactorings.
- Compose Method
- Replace Conditional Logic with Strategy
- Move Embellishment to Decorator
- Replace State-Altering Conditionals with State Pattern
- Replace Implicit Tree with Composite
- Replace Conditional Dispatcher with Command
When you have a specific piece of code that you want to make into a more general-purpose class, Chapter 8, which covers the Generalization refactorings, provides excellent reference material.
- Form Template Method
- Extract Composite
- Replace One/Many Distinctions with Composite
- Replace Hard-Coded Notifications with Observer
- Unify Interfaces with Adapter
- Extract Adapter
- Replace Implicit Language with Interpreter
Even though this is a small chapter, Chapter 9 covers the Protection aspect of your code. The idea is that the refactoring is to improve the protection of existing code and will not alter the behavior of existing code.
- Replace Type Code with Class
- Limit Instantiation with Singleton
- Introduce Null Object
Chapter 10 covers the Accumulation of code. It's meant to target the improvement of code that accumulates information within an object or across several objects.
- Move Accumulation to Collecting Parameter
- Move Accumulation to Visitor
Finally, Chapter 11 is what I consider a catch-all chapter of Utility refactorings. They are considered low-level transformations used by the higher-level refactorings in the catalog.
- Chain Constructors
- Unify Interfaces
- Extract Parameter
Overall, the book has solid coding techniques and exceptional examples by the author. Even though the examples are in Java, a .NET developer can immediately and easily see the benefit of each refactoring in the book.
The fascination I have with the Addison-Wesley/Pearson signature books are three-fold.
- They are called the Signature series for a reason...it's Martin Fowler's signature on the book.
- Once you are done reading the book, it serves as a great reference when you have a question about how a particular refactoring should be approached.
- They use real-world code examples and real-world code smells (I have seen all of them!)
Again, I would definitely recommend this book for intermediate to advanced developers who are constantly refactoring legacy code and building structured code and design patterns as a result of their refactorings.