Skip to content
FollowtheDamnCode

Facade

One simple front door to a complicated subsystem, so most callers never need to learn its internals.

Big idea

A Facade is a single, simple interface in front of a set of classes that are powerful but fiddly to use together. It doesn't hide the subsystem — experts can still reach in — it just gives everyone else one obvious call for the common case.

The problem it solves

Placing an order touches five services in a fixed order: reserve stock, charge the card, release stock if the charge fails, create a shipment, send a confirmation. Every place that places an order — the web checkout, the mobile API, the admin "reorder" button — repeats those steps, and each copy handles the failure case slightly differently. Callers are coupled to five classes and to the order in which they must be called.

Think of it like

A hotel concierge. "Dinner for two at eight, and a taxi afterwards" — one request. Behind it the concierge phones the restaurant, checks your loyalty tier, books the cab, and puts it on your room bill. You can still call the restaurant yourself; most guests never need to.

Structure

Clients call the facade; it coordinates the subsystem
What one place_order() call does

In code

Five services, one call, failure handled once
class Inventory:
    def __init__(self): self.stock = {"mug": 3, "lamp": 0}
    def reserve(self, items):
        if any(self.stock.get(i, 0) < 1 for i in items):
            return False
        for i in items: self.stock[i] -= 1
        return True
    def release(self, items):
        for i in items: self.stock[i] += 1

class Payments:
    def charge(self, card, amount):
        return not card.startswith("0000")       # pretend these cards decline

class Shipping:
    def __init__(self): self.next_id = 100
    def create(self, user, items):
        self.next_id += 1
        return f"TRK{self.next_id}"

class Notifier:
    def confirm(self, user, tracking): print(f"  mail to {user}: shipped as {tracking}")


class OrderFacade:
    PRICES = {"mug": 8, "lamp": 30}
    def __init__(self):
        self.inventory, self.payments = Inventory(), Payments()
        self.shipping, self.notifier = Shipping(), Notifier()

    def place_order(self, user, items, card):
        if not self.inventory.reserve(items):
            return "out of stock"
        if not self.payments.charge(card, sum(self.PRICES[i] for i in items)):
            self.inventory.release(items)          # the rollback lives here, once
            return "payment declined"
        tracking = self.shipping.create(user, items)
        self.notifier.confirm(user, tracking)
        return tracking


shop = OrderFacade()
print(shop.place_order("ana", ["mug"], "4242"))
print(shop.place_order("bo", ["mug"], "0000-1111"))
print(shop.place_order("cy", ["lamp"], "4242"))
print("mugs left:", shop.inventory.stock["mug"])
output
  mail to ana: shipped as TRK101
TRK101
payment declined
out of stock
mugs left: 2

Run and edit it in the app.

The declined order released its mug, so stock is correct — and that rule is written once, not once per caller.

Does a Facade prevent clients from using the subsystem classes directly?

Watch it

When to use it — and when not to

Use it when a subsystem has many moving parts and a few common workflows, to give layers a clear entry point (the service layer in front of the domain), or to wrap a sprawling library behind the three calls your app actually needs. Watch it doesn't grow into a god object that every feature edits — split facades by use case when that happens.

Pros and cons

ProsCons
Callers depend on one class, not fiveCan become a god object everyone changes
Workflow order and rollback live in one placeHides costs: one call may do a lot of work
Easier to swap subsystem internalsA second abstraction layer to maintain

How it relates

  • Adapter makes one class fit an existing interface; Facade defines a new, simpler one over many classes.
  • Mediator also centralises coordination, but its colleagues talk through it; subsystem classes don't know a facade exists.
  • Facades are often single instances (Singleton) and often built by an Abstract Factory.
  • The refactoring Hide Delegate (Moving Features) is a tiny facade.

Subsystem classes call each other through a central object and know it exists. Facade or Mediator?

Key terms

  • Facade — A simple interface that coordinates a complex subsystem for common use cases.
  • Subsystem — The group of classes the facade sits in front of.
  • God object — A class that knows and does too much, a risk for facades that keep growing.