> ## Documentation Index
> Fetch the complete documentation index at: https://akshanshgusain.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Strategy Pattern

> Behavioral Patterns

## 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.

```python theme={null}
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?

| Aspect                    | If-Else                                                           | Strategy Pattern                                                        |
| :------------------------ | :---------------------------------------------------------------- | :---------------------------------------------------------------------- |
| **Scalability**           | Hard to scale — adding new conditions requires editing the method | Easy 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 Organization**     | Logic is tangled and grows linearly                               | Logic is decoupled into separate classes                                |
| **Testing**               | Harder to unit test specific branches                             | Easier — test each strategy in isolation                                |
| **Maintenance**           | Prone to bugs as conditions grow                                  | Cleaner and maintainable                                                |
| **Reusability**           | Logic is hardcoded in one place                                   | Strategies are reusable across contexts                                 |

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