GotchaDifficulty: Advanced2 min

A Facade That Becomes a God Object

Every new feature is added to the facade, until it holds the logic the subsystem was meant to hold.

A facade calls the subsystem and decides nothing of its own, and the way it goes wrong is by being the one class every client already uses, so each new feature is added there. A god object is a class that knows and does too much of the system. This card shows an order facade on its way to becoming one, and the test that keeps a facade thin.

A facade that decides, and one that delegates

The facade decidesbusiness rules collected in the front door

py
def place_order(self, order):
    if order.total > 1000 and not order.customer.verified:
        return "needs verification"
    discount = 0.1 if order.customer.orders > 5 else 0
    pence = round(order.total * (1 - discount) * 100)
    if self._inventory.count(order.sku) < 3:
        self._email.send("[email protected]", "restock")
    ...

Fraud rules, loyalty discounts and restocking now live in the class meant only to order the calls.

The facade delegateseach rule in the service that owns it

py
def place_order(self, order):
    if not self._fraud.allows(order):
        return "needs verification"
    pence = self._pricing.total_in_pence(order)
    if not self._inventory.reserve(order.sku, order.quantity):
        return "out of stock"
    ...

The facade still orders the calls; each decision is made by the class that owns it.

The first version costs more with each feature added to it. The discount can only be applied by placing an order, so a basket page that shows the price must copy the rule. The fraud check cannot be tested without building a whole order with stock and shipping. And the facade, used by every client, becomes the file every change touches.

The test for a line in a facade is whether it chooses or only connects. Calling services in order, passing one result to the next, and undoing a step when a later one fails all connect. A threshold, a percentage or a rule about customers chooses, and belongs in a subsystem class the facade calls.