The Strategy Pattern

Definition

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

How does it work?

Think of one of those nice digital cameras with the interchangeable lenses like the one pictured below. You can change the lenses on that camera depending on the type of shot you are taking. Some lenses are better for close ups, while others are better for zooming far away. Either way, you can use the same camera for all of the pictures and all you have to do is change the lense.

This is basically how the Strategy Pattern works except in the example above, the camera is referred to as the Context and the camera lense is referred to as the Strategy. You can use the same context (camera) for multiple interchangeable strategies (lenses).

Why is this useful?

  • It can help us combine similar classes into one and extract the behavior so that it can be interchangeable.
  • We can interchange behavior or strategy even at runtime.
  • The Context class does not need to know how the Strategy works, it just uses the common interface.

Example Class Diagram

 

Example Code

For this example, we are going to mock out a player movement strategy that could be used in a game where a player would need to walk or run.

Note: The sample code is in C#. Now let’s get started.

First we need to create the interface for Stratege. Take another look at the UML Class diagram above for reference if you need to.

public interface IMoveStrategy
{
    void MovePlayer();
}

Now we will create the two movement behavior classes. Notice that they implement the IMoveStrategy interface that we implemented above.

public class WalkStrategy : IMoveStrategy
{
    public void MovePlayer()
    {
        Console.WriteLine("Player is walking.");
    }
}

public class RunStrategy : IMoveStrategy
{
    public void MovePlayer()
    {
        Console.WriteLine("Player is running.");
    }
}

Now that we have our behaviors, we can implement our player class. Take a close look at how we can change the move strategy at runtime.

public class Player
{
    private IMoveStrategy _moveStrategy;

    public void SetMoveStrategy(IMoveStrategy moveStrategy)
    {
        _moveStrategy = moveStrategy;
    }

    public void MovePlayer()
    {
        _moveStrategy.MovePlayer();
    }
}

Now it’s time to use the player and its strategies.

static void Main(string[] args)
{
    var player = new Player();
    var walkStrategy = new WalkStrategy();
    var runStrategy = new RunStrategy();

    player.SetMoveStrategy(walkStrategy);
    player.MovePlayer();

    player.SetMoveStrategy(runStrategy);
    player.MovePlayer();
}

In the above code, we are creating a new Player and both the Walk and Run Strategies. We are then using the method SetMoveStrategy() to change the behavior of the MovePlayer method. If we wanted to create a new FlyStrategy it would be very easy to do so and the player could then be able to fly along with walking and running.

I hope you have found this post helpful in learning the Strategy Pattern. If so, please share this with your fellow developers so that they too can learn.

>