Refactoring to, towards, and away from Patterns Good designers refactor in many directions, always with the goal of reaching a better design. While many of the refactorings I apply don't involve patterns (i.e., they're small, simple transformations, like Extract Method [F], Rename Method [F], Move Method [F], Pull Up Method [F], and so forth), when my refactorings do involve patterns, I refactor to, towards, and even away from patterns. The direction a pattern-directed refactoring takes is often influenced by the nature of a pattern. For example, Compose Method (123) is a refactoring based on Kent Beck's Composed Method [Beck, SBPP] pattern. When I apply Compose Method (123) , which I do often, I refactor to a Composed Method, not towards one. Refactoring towards a Composed Method doesn't sufficiently improve a method. You must refactor all the way to this pattern to achieve a genuine improvement. The same is true of the Template Method pattern [DP]. People generally apply the refactoring Form Template Method (205) to remove duplicate code in subclasses. You can't refactor towards a Template Method and expect to remove duplication. Either you implement a Template Method or you don't, and if you don't, you won't be removing duplicate code in your subclasses. On the other hand, this book contains numerous refactorings that provide acceptable design improvements whether you go towards or all the way to a pattern implementation. Move Embellishment to Decorator (144) provides a good example. An early step in the mechanics for this refactoring suggests that you use the Replace Conditional with Polymorphism [F] refactoring. Once you've done that, you can decide whether you've made a good enough design improvement to stop. If you happen to see a benefit from taking the next step, the mechanics suggest that you use the Replace Inheritance with Delegation [F] refactoring. If doing so provides a sufficient design improvement, you can stop. Or, if you see a benefit in applying all of the mechanics, you will refactor all the way to a Decorator. Similarly, if you suspect that you need to use Replace Conditional Dispatcher with Command (191), the steps you take towards a Command [DP] implementation can improve your design, regardless of whether you refactor all the way to the Command pattern. Once you've refactored to or towards a pattern, you must evaluate whether your design has indeed improved. If it hasn't, you'd better backtrack or refactor in another direction, such as away from a pattern or to another pattern. Inline Singleton (114) removes the Singleton [DP] pattern from a design. Encapsulate Composite with Builder (96) changes client code to interact with a Builder [DP] rather than a Composite. Move Accumulation to Visitor (320) replaces awkward and/or duplication-ridden Iterator [DP] code with a Visitor [DP] solution. By applying the refactorings in this book, you may refactor to, towards, or away from patterns. Just remember that the goal is always to obtain a better design, not to implement patterns. Table 3.1 lists the directions I often take when applying the patterns-based refactorings in this book. Table 3.1. Pattern | To | Towards | Away | Adapter | Extract Adapter (258), Unify Interfaces with Adapter (247) | Unify Interfaces with Adapter (247) | | Builder | Encapsulate Composite with Builder (96) | | | Collecting Parameter | Move Accumulation to Collecting Parameter (313) | | | Command | Replace Conditional Dispatcher with Command (191) | Replace Conditional Dispatcher with Command (191) | | Composed Method | Compose Method (123) | | | Composite | Replace One/Many Distinctions with Composite (224), Extract Composite (214), Replace Implicit Tree with Composite (178) | | Encapsulate Composite with Builder (96) | Creation Method | Replace Constructors with Creation Methods (57) | | | Decorator | Move Embellishment to Decorator (144) | Move Embellishment to Decorator (144) | | Factory | Move Creation Knowledge to Factory (68), Encapsulate Classes with Factory (80) | | | Factory Method | Introduce Polymorphic Creation with Factory Method (88) | | | Interpreter | Replace Implicit Language with Interpreter (269) | | | Iterator | | | Move Accumulation to Visitor (320) | Null Object | Introduce Null Object (301) | | | Observer | Replace Hard-Coded Notifications with Observer (236) | Replace Hard-Coded Notifications with Observer (236) | | Singleton | Limit Instantiation with Singleton (296) | | Inline Singleton (114) | State | Replace State-Altering Conditionals with State (166) | Replace State-Altering Conditionals with State (166) | | Strategy | Replace Conditional Logic with Strategy (129) | Replace Conditional Logic with Strategy (129) | | Template Method | Form Template Method (205) | | | Visitor | Move Accumulation to Visitor (320) | Move Accumulation to Visitor (320) | | |