Structural PatternBEGINNER6 min deep dive

Facade Pattern Pattern

Provides a simplified, unified interface to a complex subsystem of classes, libraries, or frameworks.

Real-World Mental Model / Metaphor:

A hotel concierge. You tell the concierge: 'Book me dinner and a theater ticket'. The concierge coordinates with restaurants, taxi drivers, and ticket vendors behind the scenes.

Interactive Runtime Simulator

Test and tweak inputs dynamically

Interactive Facade Pattern SimulatorLIVE PLAYGROUND

Interact with the controls below to see how this design pattern executes in memory at runtime.

Category: Structural
Configure Chain Handlers (Toggle Failures):
CHAIN PIPELINE STATUS
Step 1: AuthHandler.check() -> PASSED
Step 2: RateLimitHandler.check() -> PASSED
Step 3: PayloadGuard.check() -> PASSED
The Problem It Solves

Client code getting tangled in dozens of interdependent subsystem classes, making it difficult to maintain and tightly coupling the client to low-level implementation details.

The Architectural Solution

Introduce a Facade class that encapsulates subsystem coordination behind simple 1-line public methods.

Pattern Structure & Participants

ParticipantRole & ResponsibilityType
FacadeProvides simple methods like bookOrder() or convertVideo()class
Subsystem Classes (A, B, C, D)Complex underlying enginesclass
ClientInteracts ONLY with the Facadeclient
Collaboration Rules:
  • Client calls facade.checkout(cart)
  • Facade orchestrates Payment, Inventory, and Shipping engines in order

Production Code Implementation

Facade Pattern.java
// Complex Subsystems
public class InventoryService {
    public boolean checkStock(String productId) { return true; }
    public void deduct(String productId) { System.out.println("Stock deducted"); }
}

public class PaymentGateway {
    public boolean charge(String userId, double amount) {
        System.out.println("Charged $" + amount + " to user: " + userId);
        return true;
    }
}

public class NotificationService {
    public void sendOrderConfirmation(String userId) {
        System.out.println("Email receipt sent to " + userId);
    }
}

// Clean Production Facade
public class OrderCheckoutFacade {
    private final InventoryService inventory = new InventoryService();
    private final PaymentGateway payment = new PaymentGateway();
    private final NotificationService notifier = new NotificationService();

    public boolean placeOrder(String userId, String productId, double price) {
        if (!inventory.checkStock(productId)) return false;
        
        boolean charged = payment.charge(userId, price);
        if (!charged) return false;

        inventory.deduct(productId);
        notifier.sendOrderConfirmation(userId);
        return true; // Simplified 1-line call for the client!
    }
}
When to Use:
  • •To provide a simple, default interface to a complex subsystem.
  • •To decouple client code from the inner workings of third-party libraries.
  • •To structure subsystems into distinct layered architectural tiers.
When to Avoid (Anti-Pattern):
  • •When client code genuinely needs low-level fine-grained control over individual subsystem steps.

Staff Engineering Interview Insights & Gotchas

  • Contrast Facade vs Adapter: Facade defines a brand new simplified interface; Adapter matches an existing incompatible interface.
  • Explain how Microservice API Gateways (BFF pattern) are essentially distributed Facades.