Skip to content

Strategy Design Pattern

Video Lecture

Section Video Links
Strategy Overview Strategy Overview Strategy Overview Strategy Overview 
Strategy Use Case Strategy Use Case Strategy Use Case Strategy Use Case 

Overview

...Refer to Book, Videos or Medium Membership for extra content.

Terminology

...Refer to Book, Videos or Medium Membership for extra content.

Strategy UML Diagram

Strategy UML Diagram

Source Code

...Refer to Book, Videos or Medium Membership for extra content.

./strategy/strategy_concept.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# pylint: disable=too-few-public-methods
"The Strategy Pattern Concept"
from abc import ABCMeta, abstractmethod

class Context():
    "This is the object whose behavior will change"

    @staticmethod
    def request(strategy):
        "The request is handled by the class passed in"
        return strategy()

class IStrategy(metaclass=ABCMeta):
    "A strategy Interface"

    @staticmethod
    @abstractmethod
    def __str__():
        "Implement the __str__ dunder"

class ConcreteStrategyA(IStrategy):
    "A Concrete Strategy Subclass"

    def __str__(self):
        return "I am ConcreteStrategyA"

class ConcreteStrategyB(IStrategy):
    "A Concrete Strategy Subclass"

    def __str__(self):
        return "I am ConcreteStrategyB"

class ConcreteStrategyC(IStrategy):
    "A Concrete Strategy Subclass"

    def __str__(self):
        return "I am ConcreteStrategyC"

# The Client
CONTEXT = Context()

print(CONTEXT.request(ConcreteStrategyA))
print(CONTEXT.request(ConcreteStrategyB))
print(CONTEXT.request(ConcreteStrategyC))

Output

1
2
3
4
python ./strategy/strategy_concept.py
I am ConcreteStrategyA
I am ConcreteStrategyB
I am ConcreteStrategyC

Strategy Example Use Case

...Refer to Book, Videos or Medium Membership for extra content.

Strategy Example Use Case UML Diagram

Strategy Example Use Case UML Diagram

Source Code

./strategy/client.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# pylint: disable=too-few-public-methods
"The Strategy Pattern Example Use Case"
from abc import ABCMeta, abstractmethod

class GameCharacter():
    "This is the context whose strategy will change"

    position = [0, 0]

    @classmethod
    def move(cls, movement_style):
        "The movement algorithm has been decided by the client"
        movement_style(cls.position)

class IMove(metaclass=ABCMeta):
    "A Concrete Strategy Interface"

    @staticmethod
    @abstractmethod
    def __call__():
        "Implementors must select the default method"

class Walking(IMove):
    "A Concrete Strategy Subclass"

    @staticmethod
    def walk(position):
        "A walk algorithm"
        position[0] += 1
        print(f"I am Walking. New position = {position}")

    __call__ = walk

class Running(IMove):
    "A Concrete Strategy Subclass"

    @staticmethod
    def run(position):
        "A run algorithm"
        position[0] += 2
        print(f"I am Running. New position = {position}")

    __call__ = run

class Crawling(IMove):
    "A Concrete Strategy Subclass"

    @staticmethod
    def crawl(position):
        "A crawl algorithm"
        position[0] += 0.5
        print(f"I am Crawling. New position = {position}")

    __call__ = crawl

# The Client
GAME_CHARACTER = GameCharacter()
GAME_CHARACTER.move(Walking())
# Character sees the enemy
GAME_CHARACTER.move(Running())
# Character finds a small cave to hide in
GAME_CHARACTER.move(Crawling())

Output

1
2
3
4
python ./strategy/client.py
I am Walking. New position = [1, 0]
I am Running. New position = [3, 0]
I am Crawling. New position = [3.5, 0]

Summary

...Refer to Book, Videos or Medium Membership for extra content.