skip to content

How does the Facade pattern differ from Adapter, Mediator, and Proxy, given that all four place an object in front of something else?

level: middleimportance: must knowfreq 68%

answer

  1. Structure identical — intent differs
  2. Facade: many, new simpler interface
  3. Adapter: target interface dictated by client
  4. Proxy: same interface + access control
  5. Mediator: peers know the hub and call back

basics

~20 s

Facade simplifies many classes behind one easy entry point. Adapter converts one interface into a different one a client already expects. Mediator makes peers talk through a hub instead of each other. Proxy keeps the same interface but controls access to one object.

solid answer

~50 s

All four are wrappers; they differ by intent, by how many things they wrap, and by whether the interface changes. **Facade**: wraps *many* collaborators, invents a new simpler task-shaped interface, motivated by ease of use and reduced client coupling; the subsystem is unaware of it. **Adapter**: wraps *one* (usually) existing type and reshapes its interface to a target the client already depends on; motivated by incompatibility, typically retrofitted around code you cannot change. **Mediator**: also centralises, but it wraps *peers that would otherwise talk to each other*, and the peers know the mediator and push events into it — a bidirectional, many-to-many decoupling; Facade is one-way and its subsystem is oblivious. **Proxy**: keeps the *same* interface as its subject and adds control — lazy loading, caching, remoting, access checks — one-to-one, no simplification. Quick test: new simpler interface over many → Facade; same interface, added control → Proxy; different interface to fit an expectation → Adapter; peers decoupled from each other → Mediator.

go deeper

for a junior

Get Facade vs Adapter right with one clear example each; it is fine to be less precise about Mediator.

for a middle

Give the intent-based discriminators for all four and name the who-knows-whom rule that separates Facade from Mediator.

for a senior

Discuss overlap honestly (SLF4J facade + bindings as adapters), and explain why substitutability marks Proxy/Decorator versus non-substitutability for Facade.

for a principal

Talk about the consequences of mislabelling on module boundaries, reusability and refactoring freedom, and how naming shapes reviewer and consumer expectations.

### Why these get confused Facade, Adapter, Proxy, Decorator and Mediator all produce code shaped like `class X { constructor(private inner) {} method() { return inner.something() } }`. Structure alone cannot tell them apart — **intent** does, and interviewers probe exactly this. Three axes separate them cleanly: | Axis | Facade | Adapter | Proxy | Mediator | |---|---|---|---|---| | How many things wrapped | many (a subsystem) | usually one | exactly one | many peers | | Interface of the wrapper | brand-new, simpler, task-shaped | dictated by a *target* the client already uses | identical to the subject | new, event/notification-shaped | | Motivation | ease of use, fewer client dependencies | incompatibility between existing APIs | control access: lazy, remote, cached, guarded, logged | remove peer-to-peer wiring (n² → n) | | Does the wrapped code know? | no | no | no | yes — peers hold a reference to the mediator | | Direction | one-way (client → facade → subsystem) | one-way | one-way | bidirectional | ### Facade vs Adapter — the sharpest pair - **Adapter is driven by a pre-existing target interface.** You have `PaymentGateway` (what your code calls) and `LegacyBankSdk` (what exists). The adapter's shape is *not your choice*; it must be `PaymentGateway`. Adapter is usually applied to code you cannot modify — a third-party SDK, a legacy service, an old data format. - **Facade is driven by you.** No one dictates the shape. You invent `convert(file, format)` because that is the task your callers actually have. Nothing forces you to match an existing signature. - Number is a weak but useful heuristic: adapters usually front one thing, facades front several. It is not absolute — an adapter can compose two objects to satisfy the target, and a facade over a two-class subsystem is still a facade. - Overlap does happen. SLF4J is commonly called a logging *facade*, and it simplifies; but the per-backend bindings that translate SLF4J calls to Log4j/JUL calls are *adapters*. Real systems layer both. ### Facade vs Mediator — the subtlest pair Both centralise. The discriminator is **who knows whom** and **why they are being decoupled**. - In **Facade**, the subsystem classes are decoupled *from clients*. They still collaborate with each other freely and directly. They have no reference to the facade and would work identically if it were deleted. - In **Mediator**, the *peers* were the problem: each widget/participant referenced every other, producing an n² wiring mess. The mediator exists so peers reference only it. Peers **do** hold a mediator reference and notify it (`mediator.notify(this, "submitClicked")`), and the mediator pushes changes back into the peers. That callback direction is the tell — Facade never has it. - A dialog box where a checkbox enables a text field via `dialog.notify(...)` is Mediator. A `ReportingApi` that internally calls three repositories is Facade. ### Facade vs Proxy (and Decorator) - **Proxy** implements the *same* interface as its subject so it is drop-in substitutable, and adds a control concern: virtual proxy (lazy instantiation), remote proxy (network stub), protection proxy (authorisation), caching proxy. It does not simplify — call it and you see identical methods. - **Decorator** also keeps the same interface but adds *behaviour*, and is designed to stack recursively (`Buffered(Encrypted(FileStream))`). Facades do not stack. - If your wrapper is substitutable for what it wraps, it is Proxy/Decorator, not Facade. A facade is deliberately **not** substitutable — its interface is different and smaller. ### Decision procedure 1. Does the wrapper implement the same interface as the wrapped thing? → Proxy (control) or Decorator (added behaviour). 2. Is the wrapper's interface fixed by something the client already expects? → Adapter. 3. Do the wrapped participants hold a reference back to the wrapper and notify it? → Mediator. 4. Otherwise: new, simpler, task-shaped interface over several oblivious collaborators → **Facade**. ### Why the distinction matters practically Naming drives expectations. If you call something a facade, reviewers expect it to shrink the caller's surface and to be safely deletable without changing subsystem behaviour. If you call it an adapter, they expect an interface mismatch to justify it. Mislabelled wrappers accumulate: a 'facade' that turns out to be a mediator quietly makes the subsystem depend on it, and you lose the ability to reuse the subsystem elsewhere.

  • Can one class be both a facade and an adapter?
    In practice yes — a wrapper can simplify several collaborators and also expose them under an interface your code already expects. But when explaining it, name the dominant intent: if the shape was forced by an existing target interface it reads as an adapter; if you invented a simpler task-shaped API it reads as a facade.
  • Why is 'the subsystem doesn't know the facade' such an important part of the definition?
    Because it is the property that distinguishes Facade from Mediator and preserves reusability. If subsystem classes reference the facade, the subsystem can no longer be used without it, deleting the facade becomes a breaking change, and you have a dependency cycle.
  • Is SLF4J a facade or an adapter?
    Both, at different layers. The `LoggerFactory`/`Logger` API is a facade over logging concerns; the per-backend bindings that translate those calls into Log4j or java.util.logging calls are adapters.

saying these in an interview costs you the question

  • Distinguishing them by structure ('they all wrap something') instead of intent — all five wrapper patterns look alike in code.
  • Saying Adapter and Facade differ only by how many classes are wrapped; the real discriminator is whether an existing target interface dictates the wrapper's shape.
  • Calling a Mediator a Facade while the peers hold a reference to it — that callback direction is definitionally not Facade.
  • Saying Proxy simplifies the interface; a proxy is interface-identical and drop-in substitutable, which a facade deliberately is not.
  • Claiming a facade is just a Decorator with more objects — decorators stack and preserve the interface; facades do neither.

context