Skip to content
DevPedia

Comparisons and referenceGuide 28 of 28

Design patterns that are often confused

Some patterns have similar structures but solve different problems. What sets them apart and how to recognize when to use each.

Updated 8 min read

A good part of the GoF catalog shares structure. Adapter, Decorator, and Proxy wrap an object and delegate; Factory Method and Abstract Factory create objects behind an abstraction; Strategy and State delegate behavior to an interchangeable object. Looking at the class diagram alone, several of them are indistinguishable.

What separates them isn’t the structure but the intent: which problem they were solving. This article walks through the five groups where that confusion shows up most, and, for each one, the question that disambiguates them.

Each pattern’s own article develops the problem, the code, and when to use it. The focus here is different: naming something that’s already written correctly, or understanding what whoever wrote it had in mind.

Wrappers: Adapter, Decorator, Proxy — and Facade

Adapter and Decorator are also called Wrapper. Proxy belongs in the same group: all three take an object, hold a reference, and delegate. Facade sneaks into the comparison because it also sits in front of other code, but it doesn’t wrap an object: it offers a simple way into a subsystem.

The difference between the three wrappers is in what they change while delegating.

PatternDoes it change the interface?Does it change the behavior?How many objects?Intent
AdapterYesNoOneMake compatible what wasn’t
DecoratorNoYes, it addsOneAdd responsibilities without inheriting
ProxyNoNo: it controls accessOneDecide whether and when the real object is reached
FacadeYes, it simplifies itNoSeveralGive a simple way into a subsystem

The question that organizes the group:

  • Is the outgoing interface different from the incoming one? If it wraps an object to translate it, it’s Adapter. If it pulls several together to simplify, it’s Facade.
  • Is the interface the same? Then it’s Decorator or Proxy. If the wrapper adds observable behavior — an extra fee, a log, a validation — it’s Decorator. If the result is the same and what it decides is access — deferring the load, caching, checking permissions, talking to a remote object — it’s Proxy.

Factories: Factory Method, Abstract Factory, and Simple Factory

This is the group where the name gets confused most, partly because the third one isn’t a GoF pattern.

What it producesHow the variant is chosenIs it GoF?
Simple FactoryOne productA switch or if inside a static methodNo: it’s a common technique
Factory MethodOne productBy choosing the Creator subclassYes
Abstract FactoryA family of compatible productsBy choosing the concrete factoryYes

A static method with a switch returning new PdfExporter() or new CsvExporter() is useful and legitimate, but it isn’t Factory Method. In Factory Method the decision lives in the hierarchy: each creator subclass knows which product is its own, and there’s no conditional to update when a variant is added.

The question that organizes the group:

  • How many related products get created together? If it’s just one, look at Factory Method. If it’s several that have to be compatible with each other, it’s Abstract Factory: one factory per product doesn’t guarantee families won’t get mixed.
  • Is the variant chosen by extending a class or with a conditional? If it’s a conditional in one place and it isn’t bothering anyone, it’s a Simple Factory and that’s fine. Call it that.

Delegating behavior: Strategy, State, and Template Method

Strategy and State have practically identical class diagrams: a context with a reference to an interface, and several implementations. What tells them apart is who decides which one gets used.

PatternWho chooses the implementationDo the implementations know each other?When it changes
StrategyThe client codeNo: they’re independentWhen the client decides
StateThe states themselvesYes: each knows which it transitions toAs a consequence of an operation
Template MethodFixed by choosing the subclassIrrelevantIt doesn’t change at runtime

The decisive question: can an implementation replace itself with another? If the current state decides the next one, it’s State. If the client chooses the algorithm and the implementations don’t know each other, it’s Strategy.

The other distinction, against Template Method, is composition versus inheritance. Strategy and State change at runtime because they’re referenced objects. Template Method stays fixed: the base class fixes the sequence and subclasses only fill in the steps that vary.

Communicating changes: Observer and Mediator

Both reduce coupling between objects that need to react to each other. The difference is what the object in the middle knows.

  • In Observer the flow is one-way and anonymous: the subject announces that something happened and doesn’t know who’s listening. The observers don’t know each other and coordinate nothing. Adding an observer doesn’t change the subject.
  • In Mediator the flow is two-way and coordinated: the mediator knows the components and holds the rules for how they affect each other. A change in one can recalculate another or disable a third, and that logic lives in the mediator, not scattered across cross-references.

The question: does the central object have rules? If it just passes the notice along, it’s Observer. If it decides what to do based on who notified it, it’s Mediator. A mediator often uses Observer internally to find out about changes; they’re complementary rather than alternatives.

Saving and undoing: Command and Memento

They get confused because both show up when someone asks for “undo”.

  • Command stores the operation: what was done and with which arguments. Undoing means applying the inverse operation. It’s lighter on memory and it also lets you queue, retry, and log.
  • Memento stores the state: a snapshot of how the object was before, without exposing its private fields. Undoing means restoring the snapshot. It’s simpler to get right, and more expensive if the state is large.

The question: are you storing the operation or the state? If undoing means applying the inverse — and you also want to queue or log — it’s Command. If undoing means restoring a snapshot, it’s Memento.

In practice they combine: a Command stores a Memento of the previous state when working out the inverse operation is hard or impossible.

How to use this comparison

None of these questions helps you decide which pattern to apply to a new problem. They’re for the opposite: correctly naming something you’ve already written, or understanding what whoever wrote the code you’re reading had in mind.

For choosing, the path is still the one in the introductory article: start from the concrete problem, not from the catalog.

Share this guide

Search by concept, pattern or practice.