Definition

“Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. This pattern lets the algorithm vary independently of the clients that use it”

Explanation

You design a common Strategy interface (for example, CompressionStrategy) and implement multiple concrete strategies (e.g. ZipCompression, RarCompression). A context class holds a reference to a strategy and delegates to it. At runtime the client picks and switches strategies as needed, without changing the context’s code.

Code

In the code below, Context uses different sorting strategies (ConcreteStrategyA and ConcreteStrategyB) to sort data.

from abc import ABC, abstractmethod

class Context:
    def __init__(self, strategy: "Strategy") -> None:
        self._strategy = strategy

    @property
    def strategy(self) -> "Strategy":
        return self._strategy

    @strategy.setter
    def strategy(self, strategy: "Strategy") -> None:
        self._strategy = strategy

    def do_some_business_logic(self) -> None:
        print("Context: Sorting data using the strategy")
        result = self._strategy.do_algorithm(["a", "b", "c", "d", "e"])
        print(",".join(result))

class Strategy(ABC):
    @abstractmethod
    def do_algorithm(self, data: list) -> list:
        pass

class ConcreteStrategyA(Strategy):
    def do_algorithm(self, data: list) -> list:
        return sorted(data)

class ConcreteStrategyB(Strategy):
    def do_algorithm(self, data: list) -> list:
        return list(reversed(sorted(data)))

def main():
    context = Context(ConcreteStrategyA())
    print("Client: Strategy is set to normal sorting.")
    context.do_some_business_logic()

    print("\nClient: Strategy is set to reverse sorting.")
    context.strategy = ConcreteStrategyB()
    context.do_some_business_logic()

if __name__ == "__main__":
    main()

Analogy

A food cart where you can choose how to cook. E.g., making a burger with different patties: you change the cooking algorithm (grill vs fry vs veggie) but the steps (assemble bun, toppings) remain the same. Another example is choosing an encryption algorithm: the same plaintext, different ciphers.

Interview Insights

Common uses: When multiple ways exist to do a task (sorting, compression, encryption) and you want to switch among them dynamically. Used in UI (different rendering modes), data processing (choosing filters), AI (choosing heuristic at runtime) etc.
Advantages: Promotes open/closed principle: new strategies can be added without changing existing code. Eliminates conditional statements for choosing algorithms. Achieves loose coupling between context and algorithm
Disadvantages: May introduce many small classes for each strategy. Clients must be aware of all strategy options and choose appropriately. Can be overkill if only one or two strategies exist.\

When to use Strategy vs. State?

How to implement adding new strategies (e.g. with factory or registry)?

Advantages over using if/else or switch?

AspectIf-ElseStrategy Pattern
ScalabilityHard to scale — adding new conditions requires editing the methodEasy to scale — add a new strategy class without touching existing code
Open/Closed Principle❌ Violates it — must modify code for new logic✅ Obeys it — extend by adding new strategies
Code OrganizationLogic is tangled and grows linearlyLogic is decoupled into separate classes
TestingHarder to unit test specific branchesEasier — test each strategy in isolation
MaintenanceProne to bugs as conditions growCleaner and maintainable
ReusabilityLogic is hardcoded in one placeStrategies are reusable across contexts

Show how you’d code a strategy in your language (e.g. duck flying behaviors)