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
In code
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: 2Run 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
| Pros | Cons |
|---|---|
| Callers depend on one class, not five | Can become a god object everyone changes |
| Workflow order and rollback live in one place | Hides costs: one call may do a lot of work |
| Easier to swap subsystem internals | A 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.