Sometimes using one feature means calling several subsystem classes in order. To watch a movie on a home theater, you turn on the amplifier, turn on the projector, dim the lights, and start the player. If the client has to know this sequence and every component, it becomes tightly coupled to the subsystem. Facade places a single simple interface in front and hides that complexity.

Shared Intent

Facade has three intents.

  • A single entry point — it bundles the subsystem’s many calls into one interface. The client calls only watchMovie().
  • Looser coupling — the client does not need to know the subsystem’s internal classes. Changes inside are absorbed behind the Facade.
  • Optional use — a Facade hides the subsystem without sealing it off. A client that needs fine-grained control can still reach the internal classes directly.

The GoF Form

In GoF, a Facade is a single object that coordinates the subsystem classes. The client knows only the Facade, and the Facade owns the call order and dependencies of the internal components.

flowchart LR
    Client --> Facade
    Facade --> Amp["Amplifier"]
    Facade --> Proj["Projector"]
    Facade --> Lights
    Facade --> Player
class HomeTheaterFacade {
    private final Amplifier amp;
    private final Projector projector;
    private final Lights lights;
    private final Player player;

    void watchMovie(String title) {
        lights.dim(10);
        projector.on();
        amp.on();
        player.play(title);
    }
}

The client calls only watchMovie(). The startup order and the existence of each component stay hidden inside the Facade. The subsystem classes remain as they are; the Facade only adds a thin coordination layer over them.

Language Implementations

Java’s service layer effectively acts as a Facade. A single OrderService.placeOrder() coordinates inventory check, payment, and shipping in order. The controller never needs to know these three subsystems directly.

class OrderService {
    void placeOrder(Order order) {
        inventory.reserve(order);
        payment.charge(order);
        shipping.schedule(order);
    }
}

Python often turns a module itself into a Facade. The requests library is the classic example. It hides urllib3’s connection pooling, encoding, and redirect handling behind a single simple entry point, requests.get(url).

TypeScript makes an SDK client the Facade. It hides HTTP requests, auth token refresh, and serialization inside and exposes only methods like client.users.list(). The user need not know the complexity behind it.

Distinguishing from Adapter and Mediator

All three stand in front of other objects, but their goals differ.

  • Facade — gives a simple entry point to a complex subsystem. The direction is one-way, from client to subsystem.
  • Adapter — converts an interface. The goal is to fit an existing class to a different interface the client expects.
  • Mediator — centralizes interaction among objects. Instead of referencing each other directly, objects coordinate two-way through the Mediator.

Facade is simplification, Adapter is conversion, Mediator is coordination.

Conclusion

Facade provides a simple entry point to a complex subsystem and lowers coupling. Because it hides the subsystem without sealing it, most clients use only the Facade and reach inside only when they need fine-grained control. The decision comes down to one question.

  • Does the client have to know the call order and dependencies of several components? Then move that coordination into a Facade.

A service layer, a library SDK, and a module interface are all practical forms of Facade. What separates it from the interface-changing Adapter and the two-way Mediator is its goal.

References

  • Decorator — another structural pattern that wraps an object
  • Factory — the same GoF series
  • GoF — Design Patterns: Elements of Reusable Object-Oriented Software (1994)