Design Patterns Tutorial 0/70 lessons ~6 min read Lesson 7

    The Pattern Selection Framework

    Pattern selection is where engineers most often lose composure — too many patterns, too many trade-offs, too much taste.

    Course progress0%
    Focus
    21 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Pattern selection is where engineers most often lose composure — too many patterns, too many trade-offs, too much taste. This lesson gives you a five-step framework you can apply in a code review, a design doc, or an interview: Smell → Force → Candidates → Trade-offs → Decision.

    When practiced, this framework turns a thirty-minute debate into a five-minute answer. It also produces the artifact every senior team needs: a documented decision with rationale, alternatives considered, and a kill-switch.

    The story

    In a staff-engineer panel interview, a candidate was given a 200-line file and asked: "What patterns would you apply?" Instead of naming patterns, she walked through Smell → Force → Candidates → Trade-offs → Decision in eight minutes, named only one pattern (Strategy), and explained why she rejected Factory and State. She got the offer. The framework — not the pattern name — was the signal.

    The business problem

    Without a shared selection framework, pattern decisions become expensive opinion battles:

    • Recency bias: engineers apply whichever pattern they read about last week.
    • Design review gridlock: three engineers propose three patterns; no shared vocabulary to converge.
    • Undocumented decisions: ADRs name the pattern but not the alternatives rejected — future teams cannot tell if thinking was thorough.
    • Over-application: multiple patterns ship in one refactor because nobody ran a structured comparison.
    • Interview failure: candidates name patterns without smells, forces, or trade-offs — instant junior signal.

    The problem teams faced

    Teams without a selection framework hit the same dysfunction repeatedly:

    • Engineers reach for patterns by name instead of by fit to a documented force.
    • Design reviews become taste debates — "I don't like this" with no structured rebuttal.
    • ADRs lack an "alternatives considered" section — decisions look arbitrary in hindsight.
    • Junior engineers copy patterns from tutorials without diagnosing the smell first.

    Understanding the topic

    Five steps. Every pattern decision. No shortcuts on steps 3 and 5.

    • 1. Smell — what concrete symptom triggered this? (Switch on Type, Shotgun Surgery…).
    • 2. Force — what varies? What stays stable? Show git or roadmap evidence.
    • 3. Candidates — list two or three patterns that fit; refuse to decide with only one option.
    • 4. Trade-offs — files added, learning curve, performance, test complexity — make it explicit.
    • 5. Decision — pick one, pick none, document rationale, and define a kill-switch.

    Internal architecture

    The framework in one view — print this for design reviews:

    text
    SMELL → Switch on Type in NotificationRouter (42 branches)
    FORCE → Channel varies (email/SMS/push); git: 38/47 commits
    CANDIDATES → Strategy (per channel) | Observer (fan-out) | Mediator
    TRADE-OFFS → Strategy: 3 files, clear | Observer: 5 files, decoupled
    | Mediator: overkill for 3 channels today
    DECISION → Strategy now; revisit Observer if channels exceed 6
    KILL-SWITCH → If fan-out subscribers exceed 4, re-evaluate Observer

    Visual explanation

    Three diagrams make the framework operational. The first is the five-step pipeline — your default for every pattern decision. The second shows what a complete ADR artifact contains. The third walks candidate comparison when two patterns both seem to fit.

    5-step pattern selection framework
    Smell
    Name the symptom
    Force
    What varies + evidence
    Candidates
    2–3 options minimum
    Trade-offs
    Cost vs benefit
    Decision
    Pick one or none
    Never skip Candidates — a decision with one option is a guess, not a choice.
    ADR artifact — what to document
    Context
    Smell + force + evidence
    Alternatives
    Candidates rejected + why
    Decision
    Pattern chosen or none
    Kill-switch
    Metric to reconsider
    The kill-switch is the senior signal — without it, the decision is unfalsifiable.
    Candidate comparison example
    Switch on type
    Smell identified
    Strategy
    Algorithm varies
    State
    Lifecycle varies
    Strategy wins
    Force = pricing rules
    State fits order lifecycle; Strategy fits pricing rules — the force picks the winner.

    Informative example

    Worked example — applying all five steps to a notification router with a growing switch statement:

    ts
    // SMELL: Switch on Type — 42 branches, merge conflicts every sprint
    function notify(user: User, event: Event, channel: string) {
    switch (channel) {
    case "email": return emailService.send(user, event);
    case "sms": return smsGateway.send(user, event);
    case "push": return pushProvider.send(user, event);
    // ... 39 more cases added over 2 years
    }
    }
    // FORCE: git log → 38/47 commits touched channel-specific logic
    // CANDIDATES: Strategy | Observer | Mediator
    // TRADE-OFFS:
    // Strategy — 3 impl files + interface; clearest for "pick one channel"
    // Observer — decouples publishers; worth it at 6+ subscribers, not at 3
    // Mediator — coordination overhead; no multi-party routing yet
    // DECISION: Strategy per channel; kill-switch at 6 channels or 4 subscribers
    interface ChannelNotifier {
    send(user: User, event: Event): Promise<void>;
    }
    class NotificationRouter {
    constructor(private channels: Record<string, ChannelNotifier>) {}
    notify(user: User, event: Event, channel: string) {
    return this.channels[channel]?.send(user, event);
    }
    }
    markdown
    # ADR-014: Strategy for notification channels
    ## Context
    - Smell: Switch on Type (42 branches) in NotificationRouter
    - Force: channel-specific delivery logic varies; 38/47 git commits confirm
    ## Alternatives considered
    | Option | Pros | Cons | Verdict |
    |-----------|-------------------|-------------------------|-----------|
    | Strategy | Clear, 3 files | One interface per axis | ✅ Chosen |
    | Observer | Decoupled fan-out | 5 files for 3 channels | Deferred |
    | Mediator | Central routing | Overkill today | Rejected |
    | None | Zero indirection | Merge conflicts continue| Rejected |
    ## Decision
    Strategy per channel. Revisit Observer when subscribers exceed 4.
    ## Kill-switch
    Re-evaluate if: (a) channels > 6, or (b) events fan out to 4+ handlers per publish.

    ADR template — paste into every pattern PR:

    Execution workflow

    1Framework in a 45-minute design meeting
    1 / 5

    Name the smell

    Use Fowler's vocabulary — Switch on Type, Shotgun Surgery, Feature Envy. No smell, no pattern.

    Write the smell on the whiteboard before anyone names a pattern.

    Real-world use

    Stripe, Shopify, and Atlassian design reviews require "alternatives considered" in ADRs. Google's design doc template mandates a "decisions and trade-offs" section. Amazon's PR/FAQ process forces explicit rejection of options not chosen. The framework is not academic — it is the entry ticket to senior engineering culture. The vocabulary scales from a five-line refactor to a multi-quarter migration; only the evidence weight changes.

    Production case study

    A platform team rewrote their notification system. Three engineers each proposed a different pattern in standup — no convergence after two days:

    • Process: tech lead ran the five-step framework in a 45-minute meeting with a shared doc.
    • Smell: Switch on Type plus Shotgun Surgery across 8 files for one new channel.
    • Outcome: Observer + Strategy combo chosen with documented trade-offs; ADR referenced in 3 later refactors.
    • Timeline: implementation took 2 sprints; debate took 45 minutes instead of 2 days.
    • Lesson: structured steps convert taste debates into decisions the whole team can defend.

    Trade-offs

    • Pro — Speed: structured discussion replaces open-ended debate.
    • Pro — Inheritance: future engineers get rationale, not just code.
    • Pro — Review quality: reviewers challenge specific steps, not personal preference.
    • Con — Overhead: do not use for one-line refactors or rename-only PRs.
    • Con — Mechanical use: filling templates without thought is worse than ad-hoc.
    • Con — Writing culture: teams that skip ADRs will find step 5 painful at first.

    Decision framework

    • Always use on PRs introducing or removing a pattern in production code.
    • Always use in design docs touching more than two modules.
    • Always use in post-incident reviews when structure contributed to failure.
    • Skip on throwaway scripts, prototypes, and one-off migrations.
    • Skip when consensus exists and a current ADR already covers the case.
    • Escalate to RFC when the decision spans teams or quarters — same five steps, heavier evidence.

    Best practices

    • Write the smell on the whiteboard before anyone is allowed to name a pattern.
    • Require two candidates minimum — assign defenders so each option gets a fair hearing.
    • Every ADR needs a kill-switch with a measurable trigger, not "revisit someday."
    • Use a decision matrix when three candidates score close on trade-offs.
    • "None for now" is a valid decision — document why and what evidence would change it.
    • Link ADRs from PR descriptions so reviewers see the full framework, not just the diff.

    Anti-patterns to avoid

    • Jumping to step 5 (Decision) without listing alternatives — recency bias wins.
    • Choosing Observer because "it's modern" without a fan-out force in git log.
    • ADRs that name the pattern but skip rejected alternatives — looks thoughtful, isn't.
    • Running the full framework on a variable rename — process for process's sake erodes trust.

    Common mistakes

    • Treating candidates as rubber-stamp options when you've already decided.
    • Kill-switches without metrics — "revisit later" is not a kill-switch.
    • Forgetting step 2 evidence — force without git or roadmap data is guesswork.
    • Combining multiple pattern decisions in one ADR — one force, one decision per ADR.

    Debugging tips

    • When a past pattern decision feels wrong, re-run steps 1–2 — the force may have moved.
    • If reviewers disagree, compare filled frameworks side by side — disagreement is usually on step 4.
    • ADR archaeology: read rejected alternatives before deleting a pattern — context may still apply.
    • Spike the disputed candidate for 2 hours when step 4 trade-offs are tied — data beats debate.

    Optimization strategies

    • Keep a team ADR template in the repo — reduce step 5 friction to copy-paste.
    • For interviews, practice the framework on a 200-line file in under 8 minutes.
    • Batch pattern ADRs in refactor sprints — one meeting, multiple forces, separate ADRs.
    • Review kill-switch triggers quarterly — auto-schedule re-evaluation in the issue tracker.

    Common misconceptions

    • Many developers believe senior engineers just "know" the right pattern. In reality, they run a mental version of this framework in minutes — smell, force, reject alternatives.
    • Many developers believe ADRs are bureaucracy. In reality, a one-page ADR saves hours of re-debate when the team turns over.
    • Many developers believe more candidates means indecision. In reality, two options minimum proves you considered trade-offs.
    • Related: Change-point analysis feeds step 2; code smells feed step 1; Rule of Three gates timing.

    Advanced interview questions

    Interview Prep

    Practice concise answers, then expand each card for the explanation.

    5 questions
    1AdvancedQuestionWalk through selecting a pattern for a 500-line god class.+

    Answer

    Five steps: smells (Long Method, Divergent Change), force (git log — pricing 30×, rest minimal), candidates (Strategy, Command, none), trade-offs (3 files vs 8 vs 0), decision (Strategy for pricing only), kill-switch (revisit if command-style undo needed).

    Follow-up

    What changes at 2000 lines?
    2AdvancedQuestionWhat does a good ADR contain?+

    Answer

    Context (smell + force + evidence), alternatives with trade-offs, decision in one paragraph, and a kill-switch with a measurable trigger. Without the kill-switch, the decision is unfalsifiable.

    Follow-up

    Give an example kill-switch.
    3AdvancedQuestionHow do you handle disagreement on pattern selection?+

    Answer

    Both engineers fill all five steps independently. If disagreement is only on step 4, run a 2-hour spike on the disputed criterion. Escalate with the artifact, not opinions.

    Follow-up

    Describe a real disagreement you resolved this way.
    4AdvancedQuestionWhen is 'no pattern' the correct decision?+

    Answer

    When the force is hypothetical, the smell is single-occurrence, or trade-offs exceed benefit. Senior engineers defend 'none for now' in ADRs — it shows discipline.

    Follow-up

    Have you defended 'no pattern' under pressure?
    5IntermediateQuestionStrategy or State for a switch on order status?+

    Answer

    State if transitions and behavior per status vary (paid → shipped → delivered). Strategy if algorithms vary but lifecycle is stable. Name the force first — the smell alone does not decide.

    Follow-up

    What git evidence would you want?

    Summary

    You can now select patterns with a repeatable five-step framework, write ADRs with alternatives and kill-switches, and walk an interviewer through a 200-line file in eight minutes. Tell the staff-engineer interview story — Strategy chosen, Factory and State rejected with reasons. If you can do that without notes, you own this lesson and the Foundations module.

    Ready to mark this lesson complete?Track your journey across the entire course.