Home Design Patterns Interfaces
Interfaces
FoundationsHow the patterns differ, told entirely through what each one does to an interface.
Purpose
So many of the Gang of Four patterns are similar. It can sometimes be challenging to differentiate them. It helps me to understand patterns by how they compare in contrast, so I put together this summary of how the different pattern interfaces relate. It started as the seven structural patterns, because that is where the confusion is worst, and it grew to cover the rest of the catalog.
This page is not a pattern. It is a way of telling patterns apart. The reason it works is that a class diagram will not do the job on its own: Proxy, Decorator, Adapter, Bridge and Strategy are very nearly the same picture. The book says the difference is intent, which is true and not much help, because intent is not visible in a diagram. The interface is the closest thing to intent you can actually see in the code. One pattern keeps it, one changes it, one splits it, one narrows it, one widens it, one invents one that nobody specified. That is a fact about the source, and it is different for every pattern that shares a shape.
Design
The structural patterns first, in the order that makes the contrasts land. The first two both pretend to be an object and differ only in whether the signature changes. The next two both split an interface and differ in what they split it along.
| Pattern | What it does to the interface | The tell |
|---|---|---|
| Proxy | Provides the same interface to pretend to be an object. | The signature is identical and the caller cannot tell. Usually the real object is created late, remotely, or not at all. |
| Adapter | Provides a different interface to pretend to be a different object. | Both interfaces already existed and neither was negotiable. |
| Bridge | Splits an interface between its abstraction and its implementation. | Two hierarchies, one reference between them, and both sides expect to keep growing. |
| Flyweight | Splits an interface between shared data and object data. | An operation takes state as an argument that you would expect the object to own. |
| Composite | Unifies an interface between nodes and leaves. | The same method on a single item and on a container, and the container's version loops over its children. |
| Facade | Simplifies an interface to reduce the options. | A new, smaller interface that nobody specified, with the subsystem still reachable behind it. |
| Decorator | Expands an interface to give it more options. | The wrapper implements the interface and holds one, so it can wrap another wrapper. |
One qualification on the last row, because it is the row people argue with. A Decorator does not widen the signature that the client sees; that is exactly what it must not do, or the stack stops composing. What it widens is what a call to that interface can do. A concrete decorator is free to add operations of its own on top, but only code holding the concrete type can reach them.
The creational patterns are the same exercise applied to one specific
interface: the one you use to make an object. In every case something has been
put in front of new.
| Pattern | What it does to the construction interface | The tell |
|---|---|---|
| Abstract Factory | Replaces a set of constructors with one interface, so a whole family is chosen at once. | Several create methods on one object, and swapping that object swaps every product together. |
| Builder | Splits the construction interface from the thing being constructed. | One sequence of calls, several possible representations at the end of it. |
| Factory Method | Moves the choice of constructor behind a method a subclass overrides. | A base class that uses an object it never names. |
| Prototype | Replaces the constructor with an operation on an object that already exists. | New objects arrive by copying a configured one instead of by being built up. |
| Singleton | Replaces the constructor with an accessor, and removes the option of a second instance. | A private constructor and a static getter. |
The behavioral patterns are about the interface between objects rather than the interface of one object, but the same reading works, and it is the fastest way I know to separate the ones that keep getting confused with each other.
| Pattern | What it does to the interface | The tell |
|---|---|---|
| Chain of Responsibility | One interface, many holders. The sender never learns which one answered. | Each handler holds the next and may decline. |
| Command | Turns a call into an object, so every request has the same one-method interface. | Arguments captured as fields, and an execute() with no
parameters. |
| Interpreter | Gives every rule in a grammar the same interface, so the tree is uniform. | One class per production, all with the same evaluate method. |
| Iterator | Adds a cursor interface to a structure that has none, and hides which structure it is. | Advance, test, read. Nothing about storage. |
| Mediator | Replaces many-to-many interfaces with one hub that everybody talks to. | The colleagues know the mediator and no longer know each other. |
| Memento | Gives one object two interfaces: wide for its originator, opaque to everyone else. | A state object nobody but its owner can read. |
| Observer | Reverses the direction of the interface. You do not call the subject; it calls you. | Registration, and a notify method you did not invoke. |
| State | Keeps the object's interface fixed and swaps the object behind it. | The same call does something different later, and no branch says why. |
| Strategy | Extracts one operation into an interface of its own so it can be replaced. | The client picks the implementation and hands it over. |
| Template Method | An interface of holes. The base fixes the order, the subclass fills the steps. | A concrete method calling abstract ones. |
| Visitor | Doubles the interface: accept() on the elements, one visit
method per element type on the visitor. |
Adding an element type breaks every visitor, and that is the trade you signed up for. |
Comparisons
- Proxy and Decorator are the pair this page helps least with, because both preserve the interface exactly. The separation is ownership: a Proxy usually creates or controls its subject, a Decorator is handed one.
- Bridge and Strategy draw the same diagram. Bridge splits an interface it expects to grow on both sides; Strategy extracts one operation it expects to swap.
- State and Strategy are also the same diagram. Who chooses is the difference: the client chooses a strategy, the object chooses its own next state.
- Adapter and Facade both put a new interface in front of something. The Adapter's was specified by somebody else; the Facade's was invented.
- Composite and Decorator have almost identical structure. One holds many children to build a shape, the other holds one child to add behavior.
Why It Exists
My take
The pressure that produced this page is not in anybody's code. It is in the catalog. Twenty-three patterns, of which perhaps eight are genuinely the same UML picture, and the book distinguishes them by intent. That is the correct answer and it is useless in a code review, because intent is a claim about what somebody meant and you cannot diff it. The interface is the nearest visible proxy for intent that the compiler will actually check.
There is a practical payoff beyond naming things. The sentence in the middle column is a design decision, and it comes first. Once you have said out loud "this keeps the interface and adds work behind it", you have already chosen between a Decorator and a Proxy, and the class diagram falls out of that sentence rather than the other way round. Most bad pattern usage I have seen started from the picture and worked backwards, which is how you end up with a Bridge holding one implementation forever.
The other reason I think in interfaces is that they are what survives. On the manufacturing system I maintained, the code behind the order interface was rewritten twice and the database under it once, and the interface outlasted all of it. In embedded work it is worse: an interface published to a customer's integration is effectively permanent, because changing it means somebody drives to a plant. If the interface is the part you cannot take back, it is the right unit to reason about, and a catalog organized around what each pattern does to one is organized around the part that matters.
Criticisms
This is a mnemonic, not a taxonomy, and a few of the rows do a certain amount of violence to the pattern. Flyweight is a memory optimization; the split in its interface is a consequence of that, not the goal, and reading it as an interface trick will not tell you the one thing you need to know, which is whether you have enough duplicated objects to bother. Composite is really about recursion. The table gets you to the right name quickly and tells you nothing about whether you should be using the pattern at all.
It also fails exactly where it is needed most. Proxy and Decorator do the same thing to the interface, by definition, so the row cannot separate them. Bridge and Strategy have the same entry in spirit. State and Strategy differ only in who decides. Any classification built on a visible property will collapse the cases that differ in an invisible one, and those cases are precisely the ones people get wrong.
The last risk is social. A one-line summary is short enough to win an argument. "That is just a Decorator" ends a conversation that should have been about whether the interface deserves to exist. I wrote the table to get past the confusion faster, not to hand anybody a way to skip the design discussion.