SkillByAIOpen interactive version →

Lesson 12 / 25

Facade

One simple front door to a complex subsystem.

Hide the moving parts

Intent: provide a simple, higher-level interface to a set of interfaces in a subsystem. Placing an order might involve inventory, pricing, payments, shipping and email; an OrderFacade.placeOrder() hides that orchestration so controllers stay thin. Facades reduce coupling: callers depend on one object, not five. Unlike an Adapter, a Facade does not aim to match an existing interface; it defines a new, simpler one. Use it when many callers repeat the same multi-step sequence or when you want a clear boundary around a module. Avoid letting the facade grow into a god object that accumulates every operation in the system; split facades by use case.

An order placement facade

Callers make one call; the facade coordinates subsystems.

class OrderFacade {
  constructor(
    private inventory: InventoryService,
    private pricing: PricingService,
    private payments: PaymentGateway,
    private shipping: ShippingService,
    private mailer: Mailer,
  ) {}

  async placeOrder(cart: Cart, customer: Customer) {
    await this.inventory.reserve(cart.items);
    try {
      const quote = await this.pricing.quote(cart, customer);
      const payment = await this.payments.charge(customer.id, quote.totalCents);
      if (!payment.ok) throw new Error('Payment declined');
      const shipment = await this.shipping.schedule(cart.items, customer.address);
      await this.mailer.sendOrderConfirmation(customer.email, quote, shipment);
      return { orderTotal: quote.totalCents, trackingId: shipment.trackingId };
    } catch (err) {
      await this.inventory.release(cart.items);
      throw err;
    }
  }
}

// Controller stays thin
app.post('/orders', async (req, res) => {
  res.json(await orderFacade.placeOrder(req.body.cart, req.user));
});

A hotel concierge

You ask the concierge for dinner and theatre tickets; they deal with the restaurant, the box office and the taxi. You see one simple interface.

Quick check: What is a risk of a Facade that keeps growing?

  • It stops compiling
  • It turns into a god object that knows about everything
  • It forces every caller to use inheritance
  • It makes the subsystem faster
Answer

It turns into a god object that knows about everything — Keep facades focused on a use case.