← Back to Design Principles

Strategy

Design PrinciplesMid

The Question

What is the Strategy pattern and when would you use it?

What a Strong Answer Covers

  • interchangeable
  • "runtime swapping

Senior-Level Answer

The Strategy pattern is a behavioral design pattern that defines a family of algorithms, encapsulates each one, and makes them interchangeable. The key insight is that the algorithm is extracted from the context that uses it and placed behind an interface, so the context can switch algorithms at runtime without knowing the details of any specific implementation.

**Structure:** - **Context:** holds a reference to a Strategy object and delegates the work to it - **Strategy interface:** defines the method signature all concrete strategies must implement - **Concrete Strategies:** implement the algorithm variations

Python example (payment processing):

```python from abc import ABC, abstractmethod

class PaymentStrategy(ABC): @abstractmethod def charge(self, amount: float) -> bool: ...

class StripeStrategy(PaymentStrategy): def charge(self, amount: float) -> bool: # call Stripe API return True

class PayPalStrategy(PaymentStrategy): def charge(self, amount: float) -> bool: # call PayPal API return True

class Checkout: def __init__(self, payment: PaymentStrategy): self._payment = payment

def process(self, amount: float): if not self._payment.charge(amount): raise PaymentError('Charge failed') ```

The `Checkout` context doesn't know or care whether it's using Stripe or PayPal — it only calls `charge()`. Adding a new payment provider requires implementing the interface and injecting it, without modifying `Checkout`.

**When to use:** - You have multiple variations of an algorithm that differ only in behavior (sorting algorithms, compression codecs, pricing strategies, authentication mechanisms) - You want to eliminate conditionals that select algorithm variants (`if payment_type == 'stripe': ... elif payment_type == 'paypal': ...`) - You need to swap algorithms at runtime based on configuration or user selection - You want to test each algorithm in isolation

**Python-specific note:** In Python, first-class functions often replace full Strategy classes for simple cases. Passing a callable is idiomatic when the strategy has a single method:

```python def checkout(amount, charge_fn): return charge_fn(amount)

checkout(100.0, stripe_charge) # just pass the function ```

Full class-based Strategy is warranted when the strategy needs state (e.g., maintaining a connection) or multiple related methods.

The Open/Closed Principle is the direct motivation: the system is open for extension (new strategies) but closed for modification (context unchanged).

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Correctly defines the pattern (interchangeable algorithms behind an interface), gives a concrete real-world example, and explains the elimination of conditionals as a motivation.

3/3 — Strong Answer

Covers structure (context/interface/concrete), real example, Open/Closed Principle connection, Python callable alternative for simple cases, and knows when class-based Strategy is warranted over simple callables.

Common Mistakes

  • Confusing Strategy with State — State changes behavior based on internal state transitions; Strategy is about interchangeable algorithms
  • Not explaining that Strategy eliminates conditionals — the 'why' is as important as the 'what'
  • Over-engineering with full Strategy classes in Python where a callable suffices
  • Not mentioning dependency injection as the mechanism for runtime switching

Follow-Up Questions

  • What is the difference between the Strategy and State patterns? — Strategy: algorithm chosen externally, doesn't change itself. State: object changes its own behavior as its internal state changes, often transitioning between states.
  • In Python, when would you use a callable instead of a class for Strategy? — Single-method strategy with no state — pass a function. Multiple related methods or stateful strategy — use a class implementing an interface.
  • How does Strategy relate to the Open/Closed Principle? — OCP: open for extension, closed for modification. Adding a new strategy is extension (new class). Context never changes. Perfect OCP demonstration.
  • How would you implement runtime strategy selection based on config? — Registry pattern: a dict mapping string names to strategy classes/instances. Load config, look up strategy, inject into context.

Related Questions

  • Singleton
  • Factory
  • Observer
  • IoC / Dependency Injection
  • High Cohesion / Loose Coupling

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout