19 — Refactoring to Patterns¶
Driving question: How can a pattern emerge through safe transformations instead of a large redesign?
Learning objectives¶
- Describe the difference between pattern application and refactoring to a pattern.
- Map code smells/forces to candidate pattern-directed transformations.
- Construct multi-step refactoring sequences with checkpoints.
- Identify when stopping before the full pattern is better.
Pattern as destination—not command¶
Refactoring to patterns starts from working code and incrementally changes structure toward a pattern when the pattern resolves existing design pressure.
Example: conditional logic toward Strategy¶
graph TD
A[Large conditional] --> B[Extract branch methods]
B --> C[Introduce common strategy interface]
C --> D[Move branch behavior into strategies]
D --> E[Inject/select strategy]
E --> F[Remove obsolete conditional]
Each step should preserve behavior and leave the code in a valid state.
Stop conditions¶
Do not assume completion of the canonical pattern is always optimal. Stop when:
- the motivating change becomes easy enough;
- further indirection adds no value;
- runtime or API constraints make the canonical form harmful;
- tests/evidence do not justify additional transformation.
Design / research exercise¶
Take an existing code example with a design smell. Propose two target patterns, construct a refactoring path for each, and explain why one path better fits the anticipated changes.
Suggested reading¶
- Joshua Kerievsky, Refactoring to Patterns.
- Fowler, Refactoring.