Compare
Symptom
Human

Several subsystems must be orchestrated together to accomplish a single user-visible task, and every consumer that wants the task has to reimplement the orchestration: call A, check result, call B, on B's failure undo A, call C, then D, then E. The orchestration is a recipe everyone reinvents, often subtly wrong.

Agent

Multi-subsystem orchestration scattered across consumers means the agent must reason about subsystem ordering, error handling, and failure recovery at every call site. Verifying 'do all consumers correctly release inventory on payment-fail' requires enumerating every consumer; static analysis cannot prove uniformity.

Goal
Human

One named entry point that owns the choreography. Consumers call submitOrder(cart, customer) and never see the five subsystems behind it. The recipe lives in one place; mistakes (forgetting to release inventory on payment failure) are fixed once.

Agent

One Facade method the agent reads end-to-end to understand the full choreography. Per-consumer reasoning collapses to 'this consumer calls submitOrder(cart, customer)' — the agent does not re-verify orchestration at each consumer site.

Before the pattern

function checkout(cart, customer) {
if (!inventory.reserve(cart.items)) {
throw new Error('out of stock');
}
const charge = payment.charge(cart.total, customer.cardToken);
if (!charge.success) {
inventory.release(cart.items);
throw new Error('payment failed');
}
const shipment = shipping.createShipment(cart.items, customer.address);
notifications.sendOrderConfirmation(customer.email, shipment.trackingNumber);
audit.recordPurchase(customer.id, cart.total);
return { orderId: shipment.trackingNumber, total: cart.total };
}
// Every consumer that calls checkout knows about 5 subsystems
// and the right ordering. Forgetting inventory.release on payment-fail
// silently leaks reserved inventory.

After the pattern

class CheckoutFacade {
constructor(inventory, payment, shipping, notifications, audit) {
this.inventory = inventory;
this.payment = payment;
this.shipping = shipping;
this.notifications = notifications;
this.audit = audit;
}
submitOrder(cart, customer) {
if (!this.inventory.reserve(cart.items)) {
throw new Error('out of stock');
}
const charge = this.payment.charge(cart.total, customer.cardToken);
if (!charge.success) {
this.inventory.release(cart.items);
throw new Error('payment failed');
}
const shipment = this.shipping.createShipment(cart.items, customer.address);
this.notifications.sendOrderConfirmation(customer.email, shipment.trackingNumber);
this.audit.recordPurchase(customer.id, cart.total);
return { orderId: shipment.trackingNumber, total: cart.total };
}
}
// Client: checkout.submitOrder(cart, customer)
Example source: Illustrative example written for this site in the spirit of Design Patterns (Gamma, Helm, Johnson, Vlissides, Addison-Wesley, 1994), chapter 4. The book's running example is a compiler with parser/lexer/codegen subsystems; this JavaScript adaptation uses an e-commerce checkout because the multi-subsystem choreography (inventory + payment + shipping + notifications + audit) makes the encapsulation payoff more visible.
Pressure
Human

Per-consumer orchestration is the worst form of Insider Trading — every consumer knows about every subsystem's interface, error modes, and ordering constraints. Adding a new subsystem (e.g., fraud check) requires hunting every consumer; changing one subsystem's interface ripples to every consumer in lockstep.

Agent

Per-consumer orchestration is N consumers × M subsystems × K error-modes = N×M×K cells the agent verifies on every change. Insider Trading is the worst input shape for the agent's verification budget: every consumer must be checked for correctness against every subsystem's contract.

Tradeoff
Human

Facade hides the subsystems but also hides which subsystems exist. Debugging a runtime error inside CheckoutFacade.submitOrder requires reading through five subsystem calls; consumers can't easily intervene mid-flow (e.g., apply a discount between inventory.reserve and payment.charge). The Facade is opaque by design, and opacity has a cost.

Agent

Facade opacity means runtime errors inside the facade reach the consumer as 'submitOrder failed' with no structural breadcrumb. The agent investigating a regression traces into the facade; stack traces span the facade + subsystem boundary, and the consumer's mental model sits one level removed from the failure.

Relief
Human

One method per user task; the orchestration lives in one tested file. New subsystems land as facade-internal additions; consumers stay unchanged. The recipe stops being tribal knowledge.

Agent

Edits scoped to the Facade; consumer code unchanged when subsystems are added or refactored; one set of tests covers orchestration and error recovery exhaustively. The agent's cross-consumer verification budget drops to zero on subsystem changes.

Trap
Human

Facades that grow into general-purpose services (CheckoutFacade.submitOrder, CheckoutFacade.refund, CheckoutFacade.modify, CheckoutFacade.audit) lose the single-task focus and become god objects. Stop and split when a facade has more than one or two user tasks; if every team adds 'one more method' it becomes the Service that everyone fears.

Agent

When the Facade grows to N user tasks (submitOrder + refund + modify + audit + ...), it becomes a god object the agent must read fully before any edit. The pattern's clarity wins were proportional to focused scope; god-facade scope reintroduces the verification problem at a higher level.