Skip to content

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.