Before you start
Facade is the most common "coordinator" pattern in real codebases. Almost every service class in a NestJS or Django app is basically a Facade — it holds a few injected collaborators and offers one method per user-facing action.
Recognize it, name it, don't over-engineer around it.
The one-line version
Facade gives you ONE method that runs multiple services in the right order with the right rules.
When to use Facade
Signals:
- Multiple places do the same coordination. Every copy of a 5-service sequence is a Facade waiting to happen.
- The steps have to happen in a specific ORDER. "Audit before returning failure." "Session before analytics." Those rules belong in ONE place.
- Callers need only ONE thing to call — not five service classes.
- You want the underlying services to stay testable on their own. Facade coordinates; it doesn't swallow.
If ANY of these fire, consider Facade. Especially if two or three fire together.
Where Facade shows up in real code
- NestJS / Django service classes —
AuthService.login()coordinates repositories, hashers, session manager, event emitters. Textbook Facade. - Payment checkout flows — coordinate cart validation, inventory hold, payment, receipt, email, analytics.
- Deploy scripts — coordinate build, upload, migrate, restart, notify.
- Order-placement flows — coordinate stock check, payment, fulfillment scheduling, confirmation email.
- API gateway endpoints — coordinate auth, rate limit, request forwarding, response transformation, logging.
Every one has the same shape: N services underneath, one method the caller invokes.
Facade vs the other "wrap-something" patterns
| Pattern | What it does |
|---|---|
| Adapter | Translates shape A to shape B. One-to-one. |
| Facade | Simplifies a whole subsystem behind one entry point. Many-to-one. |
| Decorator | Adds behavior AROUND an object with the same shape. One-to-one. |
| Proxy | Stands in for an object; controls access. One-to-one. |
Facade is the "many-to-one" one. If you're wrapping ONE thing, it's not Facade — it's one of the other three.
Common mistakes
God-class Facade. Facade with 40 methods, each doing 5 different things. You've re-created the god class Facade was supposed to prevent. Rule: one Facade per USE CASE, not one Facade per SUBSYSTEM.
Facade absorbs the services. Instead of holding
self._auth = authand delegating, the Facade re-implementsauthenticate()inside. Now you can't test auth on its own. Breaks SRP.Facade builds its own services inside
__init__. Now tests can't pass in fakes. DIP (module 2 lesson- says: pass them in.
Facade with too many methods. If your
LoginFacadehas.login(),.logout(),.reset_password(),.enroll_2fa()— that's four use cases. Consider four Facades or oneAuthFacadegrouped on purpose.
Where the rules go
Facade is where the coordination rules live. Examples from our lesson:
- "Audit BEFORE returning failure" — one place.
- "New device → send email + remember it" — both steps together.
- "Analytics AFTER session creation" — event only fires for real logins.
Every rule is a business decision. Facade is where they get enforced without spreading to callers.
The interview payoff
When an interviewer asks "walk me through the login flow" and you say: "the LoginFacade coordinates auth, session, audit, mailer, and analytics — here's the sequence and here's why the order matters", you're showing:
- You know Facade by name.
- You know WHY the sequence has a specific order.
- You know the services stay usable on their own.
That's a 30-second answer that gets you real design credit.
The decision cheat-sheet
| Situation | Pick |
|---|---|
| Multiple call sites, same sequence of N services | Facade |
| Multiple call sites, different sequences | Not Facade — probably a service layer with per-use-case methods (which is a family of Facades) |
| One call site, one-off coordination | Just inline it |
| Shape mismatch to a single service | Adapter (last lesson) |
| Services need to call EACH OTHER | Mediator (not this course) |