---
# System prepended metadata

title: Strategy Pattern General Example
tags: [Python, CMSC23, OOP, Notes]

---

# Strategy pattern

### Problem

Some systems require behavior that have to be parametrized for other behavior. This is easily done in a functional programming environment since higher order functions are used to represent these. In programming languages that don't support these features, the strategy pattern is used.

![strategy](https://raw.githubusercontent.com/HowDoIGitHelp/CMSC23MDNotes/master/Markdown%20Lecture%20Notes%20and%20Lab%20Exercises/copyright%20free%20drawings/Strategy.png)

### Solution

Functions that are not first class citizens are encapsulated inside a `Strategy` class. A strategy class simply contains the method `execute(params)`, which represents the behavior that should be passed into a higher order function. Any method that can be passed into the higher order function should realize `Strategy`.

![Strategy pattern](https://raw.githubusercontent.com/HowDoIGitHelp/CMSC23MDNotes/master/Markdown%20Lecture%20Notes%20and%20Lab%20Exercises/uml/strategy.png)

The object `params` represent the data that you need to pass into the correct class. In this pattern you pass the the whole `Strategy` realization so that `strategy.execute(params)` perform the desired behavior. You can add other methods in the `Strategy` abstraction, if it makes sense for the system. 

```python=
from abc import ABC,abstractmethod

class Strategy(ABC):
    @abstractmethod
    def execute(self,params):
        pass

class RealStrategy1(Strategy):
    def execute(self,params):
        print("real strategy 1 %s" % params)

class RealStrategy2(Strategy):
    def execute(self,params):
        print("real strategy 2 %s" % params)

class Client:
    def higherOrderMethod(self, s:Strategy, params:str):
        print("parametrized behavior:")
        s.execute(params)


s = Client()
strat1:Strategy = RealStrategy1()
s.higherOrderMethod(strat1,"data")
print()
s.higherOrderMethod(RealStrategy2(),"data")

```