Strategy

Defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

classDiagram
    class Context {
        -Strategy strategy
        +setStrategy(Strategy)
        +executeStrategy()
    }
    class Strategy {
        <<interface>>
        +execute()
    }
    class ConcreteStrategyA {
        +execute()
    }
    class ConcreteStrategyB {
        +execute()
    }

    Context o-- Strategy
    Strategy <|.. ConcreteStrategyA
    Strategy <|.. ConcreteStrategyB

When to use

Use when you want to use different variants of an algorithm within an object and be able to switch between them at runtime. Also useful when you have a lot of similar classes that only differ in the way they execute some behavior.

Explanation

Problem

You have a class that performs a specific task, but there are multiple ways (algorithms) to perform that task. hardcoding all algorithms into the class makes it huge, hard to maintain, and extending it requires changing the class itself. Using conditionals (if/else or switch) to select the algorithm complicates the code.

Solution

Extract each algorithm into a separate class with a common interface. The original class (Context) stores a reference to a Strategy object and delegates the work to it. The Context doesn’t know the concrete class of a strategy, working with all strategies via the interface.

Real world problem

  1. Navigation App: Calculating a route can be done for driving, walking, cycling, or public transport. The route building algorithm is the strategy.
  2. Payment Processing: Paying via Credit Card, PayPal, or Crypto. Each payment method is a strategy.
  3. Validation: validating a form field might require different rules (email, phone, required).
  4. Sorting: Sorting a list of items using QuickSort, MergeSort, or BubbleSort depending on the data size.

Pros and Cons

Pros Cons
- Open/Closed Principle: You can introduce new strategies without having to change the context.
- Separation of Concerns: Implementation details of an algorithm are isolated from the code that uses it.
- Runtime Switching: You can replace inheritance with composition and switch algorithms at runtime.
- Complexity: Clients must be aware of the differences between strategies to select the right one.
- Overhead: Creating additional objects for each strategy increases the number of classes in the application.

Comparison

  • State: Structure is similar, but intent is different. State is about discrete states and transitions (automata), Strategy is about interchangeable algorithms. In State, the state often changes itself; in Strategy, the client usually sets the strategy.
  • Template Method: Uses inheritance to vary parts of an algorithm. Strategy uses composition. Template Method works at the class level (static), Strategy works at the object level (dynamic).
  • Command: Command encapsulates a request as an object to be executed later. Strategy encapsulates an algorithm to be executed immediately in a specific context.

Code example

Typescript

Php