AcademyDesign Patterns
Facade pattern
Hiding a multi-step subsystem behind one simple call, the second thing to maintain the facade can become, and the wall it becomes once it is the only way in.
5 min readUpdated 3 exercises
Facade hides complexity rather than translating or adding to it: one simple entry point standing in front of a subsystem that has several moving parts and a specific order they need to run in.
A Facade doesn't add behavior or translate an interface, it hides one. Several subsystems each with their own setup order and quirks get collapsed behind a single method that knows the right sequence, so callers stop needing to know it too.
The problem it solves
Starting your application takes three steps: connect to the database, warm the cache, initialize authentication. The order matters, because the cache warm-up reads from the database and authentication needs both.
If every entry point repeats those steps, you get problems that only show up later:
- Duplicated sequences. The API server, the background worker and the test setup each copy the three calls.
- Order bugs. One copy swaps two lines and the failure only appears in that entry point.
- Coupling. Every caller knows the internals of three subsystems, so changing one touches all of them.
The fix is one object that owns the sequence and exposes a single method. Callers say what they want, start(), and the facade knows how.
Structure
Two parts:
- The subsystems: the classes doing the real work (
Database,Cache,Auth). They stay unchanged and know nothing about the facade. - The facade (
AppFacade): a class exposing a small, task-oriented interface and orchestrating the subsystems.
class Database { connect() { return 'db-connected'; } }
class Cache { warm() { return 'cache-warmed'; } }
class Auth { init() { return 'auth-ready'; } }
class AppFacade {
constructor() {
this.db = new Database();
this.cache = new Cache();
this.auth = new Auth();
}
start() {
return [this.db.connect(), this.cache.warm(), this.auth.init()];
}
}
// new AppFacade().start() → ['db-connected', 'cache-warmed', 'auth-ready']The facade is not a wall. Advanced callers can still reach the subsystems directly when they need something the facade doesn't offer. It exists to make the common path short, not to forbid the rest.
Where it is used in real systems
| Use case | What the facade hides |
|---|---|
| Service layer | placeOrder() coordinating inventory, payments, email and analytics. |
| Application bootstrap | Database, cache, queues and auth started in the right order. |
| SDK wrappers | A Storage.upload() hiding signed URLs, multipart uploads and retries. |
| Complex libraries | A simple render(template, data) over a parsing and compiling pipeline. |
| Legacy systems | A clean API in front of a tangle of old modules. |
| Media conversion | convert(file, 'mp4') hiding codecs, buffers and temp files. |
| Test setup | One createTestApp() that builds the server, database and fixtures. |
If a piece of code calls three or four other objects in a fixed order just to do one thing, that sequence wants to be a facade.
Facades you already use
- `fetch(url)` hides sockets, redirects, headers and streaming behind one call.
- jQuery `$` was a facade over the inconsistent browser DOM APIs.
- Prisma Client is a facade over connection pooling, query building, SQL generation and result mapping.
- NestJS and Angular services. A service that composes several repositories or clients behind business-level methods.
- `git pull` runs fetch then merge. A small facade over two commands.
Facade, Adapter and Mediator
| What it does | Direction | |
|---|---|---|
| Facade | Offers a simpler interface to a subsystem | Callers to the subsystem |
| Adapter | Makes one interface match another | Between two incompatible interfaces |
| Mediator | Coordinates objects that talk to each other | Between peers |
A facade only simplifies. The subsystems don't know it exists. A mediator, by contrast, is known to the objects it coordinates, and they talk through it.
When not to use it
- The subsystem is already simple. A facade over one class that has one method is a pointless layer.
- It becomes a god object. A facade that grows every method any caller ever wanted turns into a dumping ground. Keep several small facades, each for one task.
- It contains business rules. A facade coordinates, it doesn't decide. When it starts holding logic, that logic belongs in a real service.
- It blocks needed access. If callers must reach around it constantly, the facade is missing something.
What interviewers ask
- "What is the Facade pattern?" A simple interface to a complex subsystem.
- "Facade versus Adapter?" A facade simplifies many things. An adapter reshapes one interface to match another.
- "Does the facade replace the subsystem?" No. The subsystems remain available. The facade is a convenience.
- "Give a real example." A service layer method that coordinates several repositories, or Prisma Client.
- "How does it help testing?" Callers depend on one small interface, so it is easy to fake, instead of mocking three subsystems.
The mistake to avoid
A Facade that does the work itself instead of delegating. Once AppFacade contains connection logic or cache rules of its own, it has become a fourth subsystem and callers cannot tell what is simple entry point and what is logic. The facade should only call the subsystems, in order, and return.
The mechanism above, one object calling several others in a fixed order, is the same in JavaScript, Python or Java. Only the syntax changes.
Now practice it
1 challenge · 2 quizzesReading this page is the cheap half. These are the exercises that make you use it.
- FacadeProCollapse a multi-step subsystem behind one call and prove the pieces still work standalone — the shortcut, not a wall, this page insists on.ChallengeSolve · EasyChallengeSolve · Easy
- Design Patterns · Structural PatternsTen quick questions across Adapter, Decorator, Facade, Proxy, Bridge, Composite and Flyweight, to check the mental model before this one.QuizTake · MediumQuizTake · Medium
- Design Patterns · Structural Patterns — Series 2ProA second, tougher pass on the same structural family, for once the first set feels easy.QuizTake · MediumQuizTake · Medium
Read next
Adapter pattern
Translating an interface you cannot change into the one callers expect, the extra hop every call pays, and the moment it adds behavior and becomes a Decorator.
5 min
Proxy pattern
Controlling access to, or deferring the cost of, an object behind its own interface, the extra hop easy to forget, and the moment it carries logic and becomes a Decorator.
7 min