Loading content...
Pattern matching tells you which patterns could work. Pattern selection tells you which pattern should work. These are fundamentally different skills.
Consider a common scenario: You're designing a notification system where events in one component need to trigger actions in others. Your pattern matching skills correctly identify Observer, Mediator, and Event-Driven Architecture as potential solutions. But which do you choose? Factory Method or Abstract Factory? Strategy or State? Template Method or Strategy?
The curse of knowledge is having options without criteria for choosing.
This page equips you with the analytical frameworks to transform ambiguity into confident decisions. You'll learn to evaluate patterns against multiple dimensions, understand the trade-offs each pattern introduces, and develop the nuanced judgment that distinguishes competent architects from exceptional ones.
By the end of this page, you will understand how to evaluate competing patterns using structured criteria, analyze the trade-offs inherent in each pattern choice, and apply contextual factors—team expertise, codebase conventions, performance requirements—to make optimal pattern selections.
Expert pattern selection isn't a single-axis optimization. It's a multi-dimensional trade-off analysis where different criteria may favor different patterns. The key is to explicitly identify and weight the dimensions that matter most for your specific context.
The Seven Dimensions of Pattern Evaluation:
Every pattern can be evaluated across these dimensions, and your context determines which dimensions carry the most weight:
| Dimension | Definition | Key Questions |
|---|---|---|
| Conceptual Fit | How well the pattern's intent matches the problem | Does the pattern solve precisely this problem? Or is it a partial match requiring adaptation? |
| Complexity Cost | The structural complexity the pattern introduces | How many new classes/interfaces? How hard to understand for new team members? |
| Flexibility Provided | The degree of future variation the pattern enables | Does the flexibility match actual or expected variation? Or is it over-generalized? |
| Coupling Impact | How the pattern affects dependencies between components | Does the pattern reduce unwanted coupling? Does it introduce new coupling? |
| Testability | The pattern's effect on testing ease | Can components be tested in isolation? Does the pattern require complex test setup? |
| Performance | Runtime efficiency implications | Does the pattern add indirection that affects performance? Is this acceptable? |
| Convention Alignment | Consistency with existing codebase patterns | Does the team already use this pattern? Will it create stylistic inconsistency? |
Weighted Evaluation:
Not all dimensions are equal in every context. A high-frequency trading system weights Performance higher than Flexibility. A startup's MVP might weight Complexity Cost (time to implement) over Convention Alignment. A regulated healthcare system might weight Testability above all else.
The first step in pattern selection is determining your dimensional weights.
Before comparing patterns, write down which 2-3 dimensions are most critical for your context. This prevents unconscious bias toward patterns you're more familiar with and ensures your selection aligns with actual project needs.
Every pattern embodies design trade-offs. There is no universally 'best' pattern—only patterns that are best for a given context. Understanding these inherent trade-offs enables informed selection.
The Universal Trade-off Spectrum:
Most pattern trade-offs fall along familiar spectrums:
The Selection Dilemma:
Both patterns address varying behavior. When do you choose one over the other?
| Criterion | Strategy | Template Method |
|---|---|---|
| Variation Granularity | Entire algorithm varies | Only specific steps vary |
| Object Composition | Uses composition (has-a) | Uses inheritance (is-a) |
| Runtime Flexibility | Strategy can be swapped at runtime | Fixed at object creation |
| Multiple Variations | Can combine multiple strategies | Single inheritance limits variations |
| Code Reuse | No inherent reuse between strategies | Base class provides reusable structure |
| Coupling | Strategies are fully independent | Subclasses coupled to parent's structure |
Selection Heuristics:
→ Choose Strategy when: Algorithms are fundamentally independent; runtime switching is needed; you want to avoid deep inheritance hierarchies.
→ Choose Template Method when: There's a genuine common structure with well-defined extension points; the 'framework' aspect is valuable; you want to enforce step ordering.
Pattern selection doesn't occur in a vacuum. The right pattern for a greenfield project with an expert team differs from the right pattern for a legacy codebase with junior developers. Context shapes optimal choices.
Key Contextual Factors:
A technically superior pattern that only you can understand is organizationally inferior to a simpler pattern that the whole team can maintain. Engineering decisions occur within social systems, not just technical ones.
The Context Assessment Checklist:
Before selecting a pattern, explicitly assess:
A recurring theme in expert pattern selection is a bias toward simplicity. Experienced architects often choose simpler solutions than novices, not because they don't know sophisticated patterns, but because they understand the costs of unnecessary complexity.
The Occam's Razor of Pattern Selection:
Among competing patterns that adequately solve the problem, prefer the simplest one.
This isn't anti-intellectualism—it's engineering wisdom. Every abstraction layer, every interface, every additional class has costs:
Start simple and refactor when complexity is earned. Modern IDEs make introducing patterns into existing code straightforward. A working simple solution that needs refactoring is better than a sophisticated pattern that takes longer to build and may never need its flexibility.
Just as there are patterns, there are anti-patterns in pattern selection—recurring mistakes that lead to poor choices. Recognizing these anti-patterns helps avoid common pitfalls.
Common Selection Mistakes:
The best architects maintain awareness of their own biases. If you find yourself always reaching for the same patterns, or always advocating for sophisticated solutions, pause and question whether you're pattern matching or habit matching.
For significant pattern decisions, documenting the selection process provides value beyond the immediate choice. A Pattern Selection Record captures the reasoning for future maintainers and enables organizational learning.
Why Document Pattern Selections?
1234567891011121314151617181920212223242526272829303132333435363738394041
# Pattern Selection Record ## Context**Component**: [Name of component/subsystem]**Date**: [Decision date]**Author**: [Your name]**Status**: [Proposed | Accepted | Superseded] ## Problem Statement[Brief description of the design problem] ## Forces at Play- [Force 1]: [Description and priority]- [Force 2]: [Description and priority]- [Force 3]: [Description and priority] ## Patterns Considered### Option 1: [Pattern Name]- **Pros**: [Benefits]- **Cons**: [Drawbacks]- **Fit Score**: [1-5] ### Option 2: [Pattern Name]- **Pros**: [Benefits]- **Cons**: [Drawbacks]- **Fit Score**: [1-5] ## Decision**Selected**: [Pattern Name] **Rationale**:[Why this pattern was chosen over alternatives] ## Consequences- **Positive**: [Expected benefits]- **Negative**: [Accepted trade-offs]- **Risks**: [What could go wrong] ## Assumptions[Assumptions under which this decision is valid][If these change, reconsider the decision]This structure follows the Architecture Decision Record (ADR) format popularized by Michael Nygard. ADRs have proven effective for capturing significant decisions. Keeping pattern selection records in your codebase (e.g., docs/decisions/) creates a living history of your design evolution.
Let's apply the selection framework to realistic scenarios where multiple patterns compete.
Scenario 1: E-Commerce Pricing Engine
Requirement: 'Product prices can be modified by various factors: customer loyalty tier, promotional campaigns, quantity discounts, regional pricing, and coupons. The applicable modifiers depend on the order context, and new modifier types will be added.'
1234567891011121314151617181920212223242526272829303132333435
PATTERN CANDIDATES:==================1. Strategy Pattern - Each modifier as a strategy2. Decorator Pattern - Wrap price with modifiers3. Chain of Responsibility - Pass price through modifier chain4. Composite Pattern - Build modifier trees EVALUATION:=========== Strategy Decorator Chain of Resp CompositeConceptual Fit 3 4 4 3Complexity Cost 2 3 3 4Flexibility 3 4 4 4Testability 4 4 4 3Performance 4 3 3 3Convention Alignment 3 4 3 2 FORCES ANALYSIS:================- Modifiers are ordered (Chain/Decorator natural fit)- Modifiers can be combined (Decorator chains, CoR chains)- Independence of modifiers (Decorator isolates each)- May need to skip modifiers (CoR's specialty) DECISION: Decorator Pattern===========================Rationale: Price modifiers naturally stack/wrap. Each modifiertransforms input price to output price. Clean interface (sameinput/output type). Easy to add new decorators. Well-understoodpattern in this codebase. Alternative consideration: If modifiers can skip remainingprocessing (e.g., 'free shipping overrides all'), Chain ofResponsibility would be better. Current requirements don'tsuggest this need.Scenario 2: Document Workflow System
Requirement: 'Documents move through states: Draft, Submitted, Under Review, Approved, Published, Archived. Behavior differs by state (e.g., only Draft can be edited, only Approved can be published). Transitions follow rules (e.g., can't go from Draft to Published directly).'
1234567891011121314151617181920212223242526272829303132333435
PATTERN CANDIDATES:==================1. State Pattern - Encapsulate state-specific behavior2. Strategy Pattern - Different behavior strategies3. State Machine Library - External tool for transitions EVALUATION:=========== State Strategy State Machine LibConceptual Fit 5 2 4Complexity Cost 3 2 3Flexibility 4 3 5Testability 4 4 3Performance 4 4 3Convention Alignment 4 4 2 FORCES ANALYSIS:================- Strong state-dependent behavior (State's core strength)- Defined transition rules (State can encode transitions)- States know about other states (State handles this naturally)- Lifecycle is core domain concept (State makes it explicit) DECISION: State Pattern=======================Rationale: The problem perfectly matches State's intent. Documentbehavior fundamentally depends on internal state. Each stateknows valid transitions. The state machine IS the domain model. Why not Strategy: Strategy implies external selection of behavior.Here, behavior is inherent to document's lifecycle position. Why not State Machine Lib: Adds external dependency. State patterncaptures the model in domain code. Lib appropriate if transitionsbecome extremely complex or need visual tools.Pattern selection is where theory meets practice. Let's consolidate the key principles:
What's next:
Real-world systems rarely use patterns in isolation. The next page explores pattern combination—how patterns work together, compose, and interact to solve complex problems that exceed any single pattern's scope.
You now have frameworks for evaluating competing patterns and making informed selections. You understand trade-off analysis, contextual factors, and the importance of simplicity. In the next page, we'll explore how patterns combine to address complex design challenges.