Facade
Facade is a structural pattern that places a simplified interface over a group of complex subsystems. It lets the client achieve the desired result with a single method call, without needing to know the initialization order, dependency relationships, or calling conventions of multiple classes. Think of a hotel front desk. A guest does not need to contact room assignment, key issuance, and breakfast reservation departments separately -- the front desk handles everything at once. Multiple departments operate behind the scenes, but the guest need not be aware of that.
βΆArchitecture Diagram
π StructureDashed line animations indicate the flow direction of data or requests
As a system grows, completing a single feature often requires calling several subsystems in a specific order. Processing one order means calling authentication, inventory lookup, payment, and notification in sequence, each with its own initialization and error-handling conventions. If that logic lives directly in client code, the same orchestration is duplicated in multiple places. When one subsystem's interface changes, every client that calls it is affected. From the client's perspective, all it wants is to 'place an order,' yet it has to know the full internal structure.
Classified as a structural pattern in the GoF design patterns. As 1990s object-oriented systems grew, class counts expanded to dozens or hundreds, and having client code directly depend on subsystem internals became a maintenance bottleneck. The same situation persists today with microservice composition, SDK design, and API Gateways -- wherever 'complex internals need to be wrapped in a simple interface.' Frameworks and libraries often use Facade internally. jQuery was a Facade over browser DOM APIs, and an ORM's `save()` method is a Facade over SQL generation, connection management, and transaction handling.
Facade's structure is straightforward. A Facade class holds references to subsystem objects and exposes simple methods to the client. The sequence works like this: 1. The Client calls the Facade's `doSomething()`. 2. Inside, the Facade calls SubsystemA, SubsystemB, and SubsystemC in the appropriate order. 3. Results are combined or errors handled, then the result is returned to the Client. An important point is that a Facade hides subsystems but does not lock them away. The client can still access subsystems directly if needed. A Facade is convenience, not enforcement. This is what distinguishes a Facade from a simple wrapper.
Facade and Adapter both wrap existing code, but the intent differs. Adapter's goal is resolving interface incompatibility; Facade's goal is reducing complexity. Adapter typically wraps a single entity and converts its interface, while Facade bundles multiple subsystems into a simple entry point. Facade and Mediator are also compared. Both coordinate communication among multiple objects, but Facade focuses on one-directional simplification while Mediator mediates bidirectional interactions among objects. The question for deciding on Facade is 'Can the client get away without knowing the internals?' If the client must understand internals to use the system correctly, a Facade may create abstraction leakage instead of helping.
Commonly Compared Concepts
Adapter
A structural pattern that bridges incompatible interfaces
Facade simplifies multiple subsystems into one entry point, while Adapter converts one incompatible interface. The dividing line is whether the goal is simplification or compatibility.
Proxy
A surrogate object that controls access to the real object
Facade hides subsystem complexity, while Proxy keeps the same interface and controls how the object is accessed.
Facade is most commonly used at subsystem or tier boundaries. Instead of a controller directly orchestrating multiple services, an application service can act as a Facade, expressing one use case as one method so the controller can focus solely on HTTP request parsing. It is also central in SDK design. AWS SDK's `s3.upload()` handling multipart splitting, retries, and permission checks internally is a Facade. The user only provides a file and a bucket name. However, if a Facade takes on too many responsibilities it degenerates into a God Object. If a single Facade accumulates dozens of methods or starts handling complex conditional logic among subsystems, it becomes a new source of complexity itself. A healthy structure keeps the Facade limited to orchestration, leaving business logic within the subsystems.