Software Design Reference Core Designer · Structuring for Stability

Lesson 0008 · Core Designer · Module 2

Strategy, Adapter, and Facade, Intentionally

Lesson 0004 taught you to notice Strategy emerging. Here you learn to reach for it — and for its two structural cousins — on purpose, with the problem first.

Mission tie-in: "use patterns intentionally" means naming the problem you have before naming the pattern that fixes it. That order is the whole difference between designing and decorating.

Knowledge: three problems, three shapes

Strategyproblem: one behavior varies; the context should not. Shape: interface + implementations + delegation. You saw it emerging in lesson 0004; here you apply it before the branch chain forms, because the variation is already proven.

Adapterproblem: your code needs interface A; a service speaks interface B, and B is not yours to change. Shape: a wrapper that implements A and translates into B.

class PaymentGateway(Protocol):              # your interface: named for the need
    def charge(self, amount: Money, token: str) -> str: ...

class StripeSdkAdapter:                      # adapts a third-party SDK to it
    def __init__(self, client: StripeSDK) -> None:
        self._client = client

    def charge(self, amount: Money, token: str) -> str:
        result = self._client.payment_intents.create(
            amount=int(amount.cents), currency=amount.currency, token=token
        )
        return result.id

Note the naming: the interface is PaymentGateway, not StripeGateway. An adapter that names itself after the thing it adapts has already let the vendor define your vocabulary — the arrow you will straighten in lesson 0009.

Facadeproblem: clients must orchestrate several subsystems to do one recurring thing. Shape: one class with a few coarse methods that drive the subsystems.

class CheckoutFacade:
    def __init__(self, inventory, payments, shipping, email) -> None: ...

    def place_order(self, cart: Cart, payment_token: str) -> Order:
        self._inventory.reserve(cart)
        charge_id = self._payments.charge(cart.total, payment_token)
        order = self._shipping.create_shipment(cart)
        self._email.send_confirmation(cart.customer, order)
        return order

Three patterns, three problems: vary a behavior, translate an interface, simplify a ritual. If you cannot name which problem you have, applying any of them is decoration.

The test of intentional use: the pattern disappears from the problem. A Strategy means callers never mention variants; an Adapter means callers never see the SDK; a Facade means callers never see the subsystems.
Field notes · what it looks like in real code
The problem you haveWhat it costsThe shape that fits
the SDK is called in six filesVendor churn lands in six places, each a separate edit.Adapter: one wrapper, one place the vendor can change.
four calls that always run togetherThe ritual is copied per caller and drifts apart.Facade: one coarse method that owns the sequence.
the if-chain grew a fifth armA variation point with a growing list of branches.Strategy: one implementation per arm.
class OrderManager wrapping one callA pattern applied with no problem behind it.Delete the wrapper; call the thing directly.

Skill: match the problem to the pattern

Your code calls a legacy SOAP service whose interface you can't change. Which pattern?

Every order triggers reserve, charge, ship, email in sequence. Which pattern?

Shipping costs differ by country and change quarterly. Which pattern?

Practice on your own code

Find one recurring ritual (three+ lines repeated in several callers) and one interface mismatch in your codebase. Apply a Facade to the ritual and an Adapter to the mismatch. If you find neither, say so out loud — that's the intentional-use discipline too.

Reveal: judgment on a tricky case

An EmailSender wraps both an SMTP library and a template system. Two subsystems, one recurring job ("send a templated email to a user"). That's a Facade — but with one eye on lesson 0009: the facade is also the natural port the domain will depend on.

Your win

You can now state the problem first — varying behavior, foreign interface, repeated ritual — and reach for exactly one of the three shapes, for a reason you can defend in review.

Read and watch deeper

Describe a messy integration to your agent-teacher and ask which of the three problems it is — before either of you names a pattern.