The Facade pattern provides a unified, simplified interface to a set of interfaces in a subsystem. It defines a higher-level interface that makes the subsystem easier to use, hiding the complexity of multiple collaborating classes.

Intent and Motivation

Intent: Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.

Motivation: A home theater subsystem involves Amplifier, DVDPlayer, Projector, Screen, and Lights — each with dozens of methods. Watching a movie requires a precise sequence: dim lights, lower screen, turn on projector, set input, play DVD. Clients should not orchestrate this every time. A HomeTheaterFacade.watchMovie() encapsulates the ritual. The facade does not prevent direct subsystem access for power users; it simply offers a convenient entry point.

Facades are the most common pattern in practice — service layers, API gateways, and SDK entry points are all facades.

Structure (UML-like)

  ┌──────────┐
│  Client  │
└────┬─────┘
     │ uses simplified API
     ▼
┌──────────────┐        coordinates       ┌─────────────────────────┐
│    Facade    │ ───────────────────────► │      Subsystem          │
├──────────────┤                           │  ┌─────┐ ┌─────┐ ┌────┐│
│ + operation()│                           │  │Class│ │Class│ │Cls ││
└──────────────┘                           │  │  A  │ │  B  │ │ C  ││
                                           │  └─────┘ └─────┘ └────┘│
                                           └─────────────────────────┘
  

Participants:

  • Facade — knows which subsystem classes are responsible for a request; delegates to them.
  • Subsystem classes — implement subsystem functionality; can be used directly or through the facade.
  • Client — communicates with the subsystem through the facade (or directly for advanced use).

Java Example

  // Subsystem classes
class CPU {
    void freeze() { System.out.println("CPU freeze"); }
    void jump(long address) { System.out.println("CPU jump to " + address); }
    void execute() { System.out.println("CPU execute"); }
}

class Memory {
    void load(long address, byte[] data) {
        System.out.println("Memory load at " + address);
    }
}

class HardDrive {
    byte[] read(long lba, int size) {
        System.out.println("HardDrive read sector " + lba);
        return new byte[size];
    }
}

// Facade
class ComputerFacade {
    private final CPU cpu = new CPU();
    private final Memory memory = new Memory();
    private final HardDrive hd = new HardDrive();

    void start() {
        cpu.freeze();
        memory.load(0, hd.read(0, 1024));
        cpu.jump(0);
        cpu.execute();
    }
}

// Client — one line instead of orchestrating three subsystems
new ComputerFacade().start();
  

JavaScript Example

  // Subsystem modules
const authService = {
  login(user, pass) { console.log(`Auth: ${user}`); return { token: 'jwt-abc' }; }
};

const cartService = {
  addItem(token, item) { console.log(`Cart: added ${item}`); },
  getTotal(token) { return 99.99; }
};

const paymentService = {
  charge(token, amount) { console.log(`Payment: charged $${amount}`); }
};

const emailService = {
  sendConfirmation(user, amount) { console.log(`Email: receipt to ${user}`); }
};

// Facade
const checkoutFacade = {
  completePurchase(username, password, items) {
    const { token } = authService.login(username, password);
    items.forEach(item => cartService.addItem(token, item));
    const total = cartService.getTotal(token);
    paymentService.charge(token, total);
    emailService.sendConfirmation(username, total);
    return { success: true, total };
  }
};

checkoutFacade.completePurchase('alice', 'secret', ['laptop', 'mouse']);
  

Real-World Use Cases

Framework / System Usage
Spring @Service classes Service layer facades coordinate repositories, caches, and messaging.
SLF4J Simple logging facade hiding Logback/Log4j complexity.
AWS SDK High-level S3Client.putObject() hides HTTP signing, retries, and serialization.
jQuery $('#el').fadeIn() facades over verbose DOM APIs.
Express app structure Route handlers facade over database, cache, and auth subsystems.
Hibernate Session Facades over JDBC, connection pooling, and SQL generation.

Pros and Cons

Pros Cons
Simplifies complex subsystem usage for common workflows Facade can become a “god class” accumulating too much logic
Decouples clients from subsystem components Hides subsystem flexibility — power users may need direct access
Promotes layering and clean architecture boundaries Changes in subsystem may require facade updates
Does not prevent direct subsystem access when needed Can mask performance issues by bundling expensive operations
Improves testability by mocking one facade instead of many classes Multiple facades for the same subsystem can cause confusion

When to Use vs When NOT to Use

Use when:

  • A complex subsystem needs a simple, high-level entry point.
  • You want to decouple clients from subsystem implementation details.
  • You are layering a system (presentation → business → data access).
  • Many clients use the same orchestration sequence repeatedly.

Do NOT use when:

  • The subsystem is already simple — a facade adds unnecessary indirection.
  • Clients need fine-grained control over every subsystem operation.
  • You are converting incompatible interfaces (use Adapter).
  • The facade grows so large it becomes the entire application (refactor into smaller services).

Common Mistakes

  1. Facade with business logic — facades should orchestrate, not implement domain rules (move logic to domain services).
  2. One mega-facade for the entire application — split by bounded context or use case.
  3. Preventing direct subsystem access — facades should simplify, not lock down.
  4. Confusing Facade with Mediator — Facade is unidirectional (client → subsystem); Mediator handles bidirectional colleague communication.
  5. Returning subsystem objects from facade methods — leaks abstraction; return DTOs or primitives.
  • Adapter — wraps one object to match an interface; Facade simplifies many objects into one interface.
  • Mediator — colleagues communicate through mediator; Facade is a one-way simplification layer.
  • Abstract Factory — can provide subsystem objects that a Facade coordinates.
  • Singleton — facades are often singletons because one entry point per subsystem is typical.
  • API Gateway (microservices) — architectural application of Facade at the network level.