Facade
A Facade is an object that provides a simple, unified interface over a set of complex subsystem classes. The client calls one or two methods on the facade; the facade coordinates the subsystem on the client's behalf. The subsystem classes still exist and can be used directly when needed — the facade does not hide them, it just makes the common path easy.
The word facade comes from architecture: the front face of a building that the public sees. The structural steel, plumbing, and electrical wiring all exist behind it, but visitors do not need to understand any of that to walk through the front door.
The problem without a facade
An e-commerce checkout involves several subsystems: inventory must be checked, a payment must be charged, a shipping label must be created, and a confirmation email must be sent. Without a facade, the calling code drives every step.
1# Bad: the controller knows the internal order of operations across
2# four subsystems. Any caller that runs a checkout must duplicate this sequence.
3class CheckoutController:
4 def post(self, order: Order) -> None:
5 if not inventory.is_available(order.sku, order.quantity):
6 raise OutOfStockError(order.sku)
7
8 charge = payment_gateway.charge(
9 amount_cents=order.total_cents,
10 token=order.payment_token,
11 )
12
13 label = shipping_service.create_label(
14 destination=order.address,
15 weight_kg=order.weight_kg,
16 )
17
18 inventory.decrement(order.sku, order.quantity)
19
20 email_service.send_confirmation(
21 to=order.customer_email,
22 charge_id=charge.id,
23 tracking_number=label.tracking_number,
24 )
Every entry point that completes an order — a web controller, a mobile API endpoint, a background retry job — must reproduce this exact sequence. When the sequence changes (say, the inventory decrement moves before the payment charge), every copy must be updated together.
How the Facade solves it
A CheckoutFacade owns the orchestration. Callers invoke place_order() and receive a
result. The subsystem classes are injected into the facade, not scattered across callers.
The client (controller, endpoint, job) depends only on CheckoutFacade. The four subsystem
classes are invisible to it.