Here’s something that tripped me up for years: some patterns have nearly identical class diagrams. Strategy and State. Decorator and Proxy. Draw them on a whiteboard and you can’t tell which is which.

That’s because a pattern isn’t its diagram. A pattern is a diagram plus an intent. Two patterns can share a structure and solve completely different problems. This post puts the eight most commonly confused pairs side by side, using the code we’ve already seen in CornerStore.


Agenda:

  1. The Cheat Sheet
  2. Strategy vs State
  3. Facade vs Mediator
  4. Decorator vs Proxy
  5. Command vs Memento for Undo
  6. Factory Method vs Abstract Factory
  7. Adapter vs Bridge
  8. Composite vs Decorator
  9. Template Method vs Strategy

The Cheat Sheet

If you only remember one line per pair:

Pair The difference in one line
Strategy vs State Strategy swaps an algorithm the caller chooses. State changes behaviour as the object’s own lifecycle moves on.
Facade vs Mediator Facade is a front door for outside callers. Mediator coordinates peers that talk through it.
Decorator vs Proxy Decorator adds a responsibility. Proxy controls access.
Command vs Memento Command records the action. Memento records the state.
Factory Method vs Abstract Factory Factory Method creates one product via an overridable method. Abstract Factory creates a matching family.
Adapter vs Bridge Adapter fixes a mismatch after the fact. Bridge separates two dimensions by design.
Composite vs Decorator Composite holds many children. Decorator wraps one component.
Template Method vs Strategy Template Method varies steps through inheritance. Strategy swaps the whole algorithm through composition.

Strategy vs State

The difference: Strategy swaps an algorithm chosen for an operation. State changes an object’s behaviour as its own lifecycle advances.

  Strategy State
In CornerStore Shipping cost: standard, express or pickup The order lifecycle: pending, paid, shipped and so on
What varies The calculation for a shipping method Which operations an order allows right now
Who decides Pricing picks the strategy from the cart’s shipping method The current state handles the request and moves the order on
Do they know each other? No. Strategies are independent. Yes. States create the next state.
Smell fixed S21: a shipping switch S20: status-string checks

How to tell which you need:

  • Choosing between different ways to do the same job? Strategy.
  • Does what’s allowed depend on where the object is in its life? State.

Common mistake: treating every swappable behaviour as Strategy, and missing the transitions that make State useful.

Read more: Strategy · State


Facade vs Mediator

The difference: Facade gives a caller a simpler way into a subsystem. Mediator coordinates communication between peer objects.

  Facade Mediator
In CornerStore CheckoutFacade.PlaceOrder CartMediator and the four cart widgets
What varies The sequence of services a checkout needs Who reacts, and in what order, when a widget changes
Who decides The caller chooses to use the facade Widgets notify the mediator, and the mediator decides what happens next
Do the others know it exists? No. Services behind a facade are unaware of it. Yes. Every colleague talks to the mediator.
Smell fixed S10: the console ran checkout itself S17: widgets updated each other directly

How to tell which you need:

  • Does one caller need an easier way to run several services? Facade.
  • Do several peers need to react to each other without holding references? Mediator.

Common mistake: both centralise calls, so they get lumped together. A facade simplifies access. A mediator defines interactions.

Read more: Facade · Mediator


Decorator vs Proxy

The difference: Decorator adds a responsibility while keeping the interface. Proxy controls access to the object behind that interface.

  Decorator Proxy
In CornerStore Gift wrap and insurance stacked around a price Caching and permission checks in front of inventory
What varies Which optional extras are added Whether, and how, a call reaches the real service
Who decides Pricing stacks the decorators when calculating add-ons The app wires the proxy in place of the service, and it applies its policy on every call
Smell fixed S09: add-on flags and an if-chain S12: uncached reads and scattered role checks

How to tell which you need:

  • Adding optional behaviour that stacks up? Decorator.
  • Managing access, caching, permissions or lazy creation? Proxy.

Common mistake: “it wraps an object, so it’s a decorator.” Wrapping is the structure. Adding versus controlling is the intent.

Read more: Decorator · Proxy


Command vs Memento for Undo

The difference: Command records an action that can be run or reversed. Memento records state that can be restored later.

  Command Memento
In CornerStore Back-office stock adjustments, refunds and cancellations Cart undo
How undo works Do the opposite: “I subtracted 4, so add 4” Put the old state back: “here’s what the cart looked like”
What else it gives you An audit log, and the option to queue actions Encapsulation: the caretaker never sees inside the snapshot
Smell fixed S14: inline actions with no undo or audit S18: public cart internals copied by hand

How to tell which you need:

  • Need to represent and manage requests, including reversing them? Command.
  • Need to restore an object’s earlier values without exposing them? Memento.

Common mistake: assuming any undo feature is one or the other. They solve undo differently, and they can be combined: a command can hold a memento of what it changed.

Read more: Command · Memento


Factory Method vs Abstract Factory

The difference: Factory Method lets a creator subclass choose one product. Abstract Factory creates a compatible family of products.

  Factory Method Abstract Factory
In CornerStore Payment creators and processors Regional pricing and money formatting
What varies Which payment processor gets created A whole set of regional rules that must match
Who decides A concrete creator overrides CreateProcessor() The app picks a regional factory, then asks it for each product
Smell fixed S03: a payment switch building processors S01: region branches that could mix rules

How to tell which you need:

  • One product varies inside a shared workflow? Factory Method.
  • Several products must stay consistent with each other? Abstract Factory.

Common mistake: thinking Factory Method is just a smaller Abstract Factory. Its key idea is the overridable method inside a creator’s workflow, not the creation itself.

Read more: Factory Method · Abstract Factory


Adapter vs Bridge

The difference: Adapter translates an existing interface that doesn’t fit. Bridge separates two dimensions so each can vary independently.

  Adapter Bridge
In CornerStore ShipFastAdapter around the courier’s XML API Order messages on one side, delivery channels on the other
When it’s applied After the fact, to make existing things fit Up front, to stop a class explosion
What varies The translation to one vendor’s protocol Message types and channels, independently
Smell fixed S06: checkout calling courier XML directly S07: one class per message-and-channel combination

How to tell which you need:

  • Using an existing service whose interface doesn’t suit you? Adapter.
  • Two things that each need their own variations and combinations? Bridge.

Common mistake: both put an interface between two sides. Adapter is about translation. Bridge is about independent growth.

Read more: Adapter · Bridge


Composite vs Decorator

The difference: Composite represents a part or a group of parts. Decorator wraps one component to add a responsibility.

  Composite Decorator
In CornerStore Bundles made of products Add-ons stacked around a base price
Holds Zero or more children Exactly one wrapped component
Combines results by Aggregating its children (a bundle sums its parts) Adding its own bit to the result underneath
Smell fixed S08: a separate bundle path with type checks S09: add-on flags and an if-chain

How to tell which you need:

  • A tree of parts and groups that callers should treat the same way? Composite.
  • Optional behaviour layered around one object? Decorator.

Common mistake: both are recursive, and both hold a component of their own type. Count the children: many means Composite, one means Decorator.

Read more: Composite · Decorator


Template Method vs Strategy

The difference: Template Method fixes an algorithm’s outline in a base class. Strategy hands the whole algorithm to a replaceable object.

  Template Method Strategy
In CornerStore CSV and JSON report exporters Shipping cost calculations
What varies A few steps inside a fixed sequence The entire calculation
Mechanism Inheritance: subclasses override steps Composition: the caller holds a different object
Smell fixed S22: two exporters duplicating one workflow S21: a shipping switch

How to tell which you need:

  • The overall sequence is fixed and only some steps differ? Template Method.
  • Callers should be able to pick or swap a complete algorithm? Strategy.

Common mistake: they both vary behaviour, so people treat them as interchangeable. The real choice is inheritance or composition, and that choice affects everything else about the design.

Read more: Template Method · Strategy


The Pattern Behind the Patterns

Looking at these eight pairs together, the same lesson keeps coming back: don’t identify a pattern by its shape. Identify it by the question it answers.

  • “How do I choose between ways of doing this?” is a different question from “how does this object’s behaviour change over time?”
  • “How do I add something?” is different from “how do I control access?”

When you’re reviewing code or designing something new, start with the question. The right pattern usually follows.

For the code side by side, the repository’s comparisons guide has CornerStore excerpts for every pair.

Next up: what happens when all 23 patterns live in the same codebase.


Previous: Visitor · Next: The Capstone