Structural PatternsFacade PatternHard⏱️ ~2 min

Facade Pattern - Trade-offs and When to Use

When to Use Facade Pattern
Use Facade When:
First, you have a complex subsystem with many interdependent classes and clients only need simplified access to common operations. Example: Home automation system with 20+ device controllers but users want single "movie mode" button.

Second, you want to layer your system where each layer provides a facade to the layer below. Example: Data Access Layer provides facade to raw database operations, hiding connection pooling and transaction management.

Third, you want to decouple clients from subsystem implementations to allow subsystem evolution without breaking client code. Example: Payment facade hides whether using Stripe, PayPal, or bank transfer.
Avoid Facade When:
First, the subsystem is already simple with 2-3 classes. Adding a facade adds unnecessary indirection. Example: A User class with UserValidator does not need a facade, just use them directly.

Second, clients need fine-grained control over subsystem behavior in most cases. The facade becomes a bottleneck. Example: A graphics rendering library where users need access to individual shader, texture, and mesh operations for custom effects.

Third, the subsystem is unstable and frequently changing. The facade API will require constant updates, negating its stability benefit. Wait until the subsystem stabilizes.
Facade vs Alternative Patterns
Facade vs Adapter: Use Facade when simplifying access to multiple classes. Use Adapter when converting interface of a single class to what client expects. Facade creates new interface, Adapter matches existing interface. Example: Adapter wraps third-party payment library to match your PaymentProcessor interface, while Facade provides checkout() that calls payment, inventory, and notification.
Facade vs Mediator: Use Facade for unidirectional simplification (client to subsystem). Use Mediator for bidirectional communication between colleague objects. Mediator knows about colleagues and vice versa, Facade is known by clients but not by subsystem. Example: Chat room uses Mediator for users to communicate, API gateway uses Facade to simplify microservice calls.
Facade vs Service Layer: Service Layer is an architectural pattern for business logic, Facade is a structural pattern for simplification. They can coexist: Service Layer methods may use Facade to access infrastructure subsystems. Example: OrderService (service layer) uses PaymentFacade (facade) to process payments.
Practical Trade-offs
AspectBenefitCost
CouplingReduces client-subsystem couplingIntroduces facade as new dependency point
ComplexitySimplifies client code dramaticallyAdds one more class to maintain
FlexibilityCan swap subsystem implementationsFacade API must remain stable
TestingEasier to mock single facade in testsFacade itself requires integration tests
Interview Tip: When asked about trade-offs, acknowledge that Facade adds a layer of indirection. However, argue that in systems with 5+ subsystem classes, the simplification benefit outweighs the cost. For systems with 2-3 classes, direct usage is often cleaner.
💡 Key Takeaways
Use Facade for complex subsystems with many classes, avoid for simple 2-3 class systems
Facade provides unidirectional simplification, unlike Mediator's bidirectional coordination
Facade reduces coupling but introduces a new dependency point that must remain stable
Best combined with layered architecture where each layer provides a facade to the layer below
📌 Examples
1Use Facade for booking system coordinating inventory, payment, and notification. Avoid for simple user registration with just validation and persistence.
2Use Facade for compiler with lexer, parser, optimizer, and code generator. Avoid for calculator with just addition and subtraction.
← Back to Facade Pattern Overview
Facade Pattern - Trade-offs and When to Use | Facade Pattern - System Overflow