Design Patterns: Strategy Pattern

·

4 min read

I am working my way through Head First Design Patterns and I will be sharing my notes on each topic. Design patterns are an important object oriented programming concept as they help software engineers have an arsenal of solutions to problems that show up often. I really want to hone in on and refine my craft as a software engineer so it makes sense to me to understand these concepts. I will share my journey along the way! I may even come up with an Anki deck of this book.

I owe a big thanks to Christopher Okhravi. Check out his YouTube series on the book here

I will put keep all my notes on this notion page here so feel free to use that as a reference. The rest of this blog post will simply be a copy paste of the information there. If you feel that my notes are lacking or incorrect in some way, please let me know! I am open to criticism.

My TL;DR Definition: Encapsulate each algorithm in a set such that they are interchangeable with each other.

Slightly Longer Definition: The strategy pattern is used when a group of algorithms (or behaviors) ought to be encapsulated in order to be interchangeable with each other. This way a client (or an implementation of a class) can be composed with these algorithms rather than be tightly coupled with a certain particular algorithm. Plug and play!

Typical Animal OOP Example: Suppose we were to create an Animal class and we know that all animals have a certain behavior of making a noise. Most animals make different noises from each other but sometimes we will have multiple instances of the same kind of animal or animals that are of different breeds but not "type" and furthermore there could be animals that don't make any noise at all. Instead of having a concrete implementation of a makeNoise behavior for each animal type, we can delegate this behavior to an interface and define an implementation of that interface elsewhere.

Pseudocode: (The code below is C#/Java-ish. Don't expect it to compile)

//before Strategy Pattern
public class Animal
{
    makeNoise()
    {
        ...
    }
}

public class Snail extends Animal {
    makeNoise()
    {
        //overriden to make no noise
    }
    //oh boy, we're gonna have to do this for EVERY
    //type of animal! What a headache...
}

//AFTER Strategy Pattern
interface INoiseBehavior
{
    void makeNoise();
}

class Bark : INoiseBehavior
{
    void INoiseBehavior.makeNoise()
    {
        //play bark.ogg
    }
}

class NoNoise : INoiseBehavior
{
    void INoiseBehavior.makeNoise()
    {
        //play nothing
    }
}

public class Animal
{
    INoiseBehavior noiseBehavior;

    public void executeNoise()
    {
        noiseBehavior.makeNoise();
    }
}

public class Dog extends Animal
{
    public Dog()
    {
        noiseBehavior = new Bark();
    }
}

public class Snail extends Animal
{
    public Snail()
    {
        noiseBehavior = new NoNoise();
    }
}
//wow so much easier to COMPOSE these classes!
//thanks Strategy Design!