If you remember five things
The whole pattern in one glance. Everything below is the defense of these five calls.
- Intent. Wrap a multi-class subsystem behind one small, friendly method so callers talk to one object, not six.
- It coordinates, never computes. A Facade delegates to existing classes. The moment it grows real business logic, it has stopped being a Facade.
- Composition, not inheritance. The Facade holds references to the subsystem and delegates. The subsystem classes never hear about the Facade and stay reusable on their own.
- Convenience, not a wall. It simplifies the common path. An advanced caller can still reach a subsystem class directly.
- The classic gotcha. It quietly becomes a God object: validation, then pricing, then caching all pile in until one class owns everything. Keep it thin.
This is a Gang of Four structural pattern, and its whole reason to exist is the Law of Demeter: a caller should talk to one friend, not to the friend's friend's friend. By the end of this page you can draw it, code it, and defend it when an interviewer pushes.
1The problem it solves#
A subsystem of five or six classes is powerful but hard to call correctly. Each class does one job, so getting something useful done means talking to all of them, in the right order, with the right data passed between them.
Picture a "place an order" flow in an online store. One order needs four steps, in sequence:
- Check the item is in stock (InventoryService)
- Charge the card (PaymentService)
- Book a courier (ShippingService)
- Email a receipt (NotificationService)
Now spread that four-step dance across your codebase. Say the order logic lives in 3 controllers, 2 background jobs, and a dozen tests:
- That is the same 4-step sequence copy-pasted in 17 places.
- Add a fraud check between steps 2 and 3, and you hunt through all 17 callers to patch every one.
- You will miss one. You always miss one.
The real pain is coupling. Every caller depends on 4 classes plus the exact order they run in:
- That is 4 reasons every caller might break when the subsystem changes.
- It is a direct Single Responsibility Principle violation: the controller now owns both "handle the HTTP request" and "know the order-placement choreography."
A Facade exists to turn "call these 6 classes in this exact order" into "call this one method," so the choreography lives in exactly one place and every caller depends on exactly one thing.
2The idea (mental model)#
Think of the front desk at a hotel. You want a late checkout, a taxi, and your bags sent up:
- You do not call housekeeping, then the garage, then the bell desk yourself.
- You talk to the front desk and say what you want. They coordinate the rest.
- The front desk does not replace housekeeping or the garage. Those still exist and still do the real work.
- It just gives you one number to call and hides the org chart.
That is the whole pattern. A Facade is a class that wraps a complicated subsystem and exposes a small, friendly method or two that do the common thing. The subsystem classes stay exactly as they are. You are only adding a simpler way in.
Two things worth locking in:
- It adds no new behavior of its own. It orchestrates existing behavior. If it starts computing things, it has stopped being a Facade.
- It does not block direct access. If an advanced caller needs a subsystem class directly, they still can. The Facade is a convenience, not a wall.
When I ask "how does a caller actually trigger all of this?", I am checking whether you think about API surface and coupling, not just boxes. The answer "I put a Facade in front so the controller calls one method" lands well. Then I will immediately test whether you know where to stop stuffing logic into it.
3Structure#
The cast is small. Three roles, and only one arrow direction matters:
- Subsystem classes do the real work.
- The Facade is the simple front.
- The Client wants the job done and talks only to the Facade.
The Facade holds references to the subsystem classes and delegates to them. Nothing inherits anything: this is composition, not inheritance. The Facade is composed of the pieces it coordinates, which is "favor composition" in practice.
BulkOrderFacade could reuse the exact same four services.Here is the same thing as a runtime flow, which is what an interviewer usually wants you to walk through:
4Implementation in Java#
Keep the subsystem classes honest but minimal. Imagine each one has real logic inside.
// --- Subsystem classes. Each knows one job and nothing about the others. ---
class InventoryService {
boolean reserve(String itemId) {
System.out.println("Reserved " + itemId);
return true;
}
}
class PaymentService {
boolean charge(String cardToken, double amount) {
System.out.println("Charged " + amount);
return true;
}
}
class ShippingService {
String schedule(String itemId, String address) {
System.out.println("Courier booked to " + address);
return "TRK-" + itemId.hashCode();
}
}
class NotificationService {
void sendReceipt(String email, String trackingId) {
System.out.println("Receipt to " + email + ", track " + trackingId);
}
}
Now the Facade. One method, one clear job, all the orchestration hidden inside it.
class OrderFacade {
private final InventoryService inventory = new InventoryService();
private final PaymentService payment = new PaymentService();
private final ShippingService shipping = new ShippingService();
private final NotificationService notifier = new NotificationService();
// The client calls only this.
public String placeOrder(String itemId, String cardToken,
double amount, String address, String email) {
if (!inventory.reserve(itemId)) {
return "FAILED: out of stock";
}
if (!payment.charge(cardToken, amount)) {
return "FAILED: payment declined";
}
String trackingId = shipping.schedule(itemId, address);
notifier.sendReceipt(email, trackingId);
return "CONFIRMED: " + trackingId;
}
}
And the client, which is now blissfully dumb:
public class Store {
public static void main(String[] args) {
OrderFacade orders = new OrderFacade();
String result = orders.placeOrder(
"BOOK-42", "tok_abc", 499.0,
"12 MG Road", "buyer@example.com"
);
System.out.println(result);
}
}
Notice what the client does not know:
- That there are four services at all.
- The order they run in.
- That stock is checked before the card is charged.
The day I add a fraud check, I touch one file: the Facade. One file instead of 17.
Reveal the answer
The fix is constructor injection. Pass the services in so you can swap mocks in tests:
class OrderFacade {
private final InventoryService inventory;
private final PaymentService payment;
// ... accept the rest via constructor too
OrderFacade(InventoryService inventory, PaymentService payment /* ... */) {
this.inventory = inventory;
this.payment = payment;
}
}
Now a unit test can hand the Facade a PaymentService stub that returns false and assert you get back "FAILED: payment declined" without touching a real gateway.
5A real-world example#
You already use Facades every day. The order flow above is the textbook case, but the pattern hides inside tools you ship with:
- SLF4J and logging. Your app calls
logger.info(...). The name says it: SLF4J is the Simple Logging Facade for Java. Behind one call, a subsystem picks the backend (Logback, java.util.logging), formats the message, and routes it. Swap Logback for Log4j2 and not onelogger.infocall changes. - JDBC-style data access. A
UserRepositorywithfindByIdandsavehides connection pooling, prepared statements, result-set mapping, and transactions. The caller just wants a user, not 5 steps of boilerplate. - Compiler and build tools. One build command kicks off parsing, dependency resolution, compilation, and packaging in order. You are not calling each phase yourself.
- Payment integrations. A
Payments.charge(...)wrapper hides Stripe, retries, idempotency keys, and currency conversion. The rest of the app does not know Stripe exists, so adding a second gateway touches one class.
In an LLD setting, the tell is a "do the whole thing" operation. Any time your problem fans a single verb (place order, start a ride, book a movie seat, publish a post) out into several subsystems, a Facade is the natural coordinator.
6When to use it, and when not to#
Facade earns its place
- Too many classes
- A subsystem has grown enough that callers struggle to use it correctly.
- Repeated dance
- The same multi-step sequence is copy-pasted in many places.
- Vendor lock-in
- You want to wall off a third-party library so you can swap it. The Facade acts as an anti-corruption layer: the vendor's types stop at the door.
- Layering
- Each layer exposes one clean entry point to the layer above.
Facade is just noise
- Already simple
- The subsystem is one or two classes. Wrapping two calls in a third class adds nothing.
- Fine-grained control
- Callers genuinely need direct access. Forcing a narrow door frustrates people, and they reach around it.
- Logic creep
- You are tempted to put business rules inside. If logic lives nowhere else, it is a God object wearing a disguise.
A Facade should feel like it could be deleted and the subsystem would still work. It is a convenience layer, not the brain.
7Common mistakes#
These are the ones that come up in interviews, and the first two fail candidates.
- Turning it into a God object. The most common failure. The Facade starts thin, then someone adds validation, then pricing math, then a cache, and now 800 lines of unrelated logic live in one class. That breaks Single Responsibility hard. It delegates; it does not compute.
- Forcing all access through it. A Facade simplifies the common path, it does not forbid the uncommon one. If an advanced caller needs
InventoryServicedirectly, let them. A sealed-off subsystem is a liability. - Confusing it with Adapter. Adapter changes an interface to match what a client expects (a square peg into a round hole). Facade simplifies interfaces that already work. Adapter is about compatibility, Facade about convenience. Giveaway: Adapter usually wraps exactly one class, Facade fronts several.
- Confusing it with Mediator. Mediator sits between peers so they can talk without direct links. Facade sits in front of a subsystem so an outsider can talk to it easily. Mediator faces inward, Facade faces outward. Also: subsystem classes know about the Mediator, but they never know about the Facade.
- Leaking subsystem types in the signature. If
placeOrderreturns anInventoryReservationfull of internal fields, you just leaked the subsystem to the client, and now they depend on it anyway. Return simple results or your own clean DTO.
Putting real business rules inside the Facade and calling it clean design. If I ask "where does the fraud scoring live?" and your answer is "in the Facade," I have watched you rebuild the God object the pattern was meant to prevent. The Facade routes the call to a fraud service. It does not score the fraud.
8Where it shows up in interviews#
Facade rarely headlines, because it is Easy. It plays a supporting role inside a bigger design, and knowing to name it scores points.
- Expect it when you design an order service, a ride-booking flow, a notification system, or a payment module.
- You will sketch several services, then the interviewer asks "how does a caller actually trigger all of this?"
- The answer: "I put a Facade in front so the controller calls one method." That shows you think about API surface and coupling.
"How is this different from an Adapter?"
"Where do you draw the line between a Facade and a God object?"
"How would you make this testable?"
"Should the Facade stop callers from reaching the subsystem directly?"
"Is this the same as Mediator?"
What you can now explain in the room
- The intent in one sentence: one simple entry point in front of a multi-class subsystem.
- Why it cuts coupling: callers depend on one stable interface, not on the shape of the subsystem.
- That it is composition, not inheritance, and that the subsystem never knows the Facade exists.
- When to reach for it and one honest case where it is just noise.
- The God-object trap, and why the Facade routes but never computes.
- How Facade differs from Adapter (compatibility) and Mediator (inward-facing peers).
Next, I would study the Adapter pattern (its most-confused cousin) and the Mediator pattern, then try applying Facade inside a full "design an order management system" LLD problem.
Get a prep plan built around your Facade Pattern interview
Tell us the role and your interview date. We will send back a dated, day by day plan. Free.