What is the difference between Strategy design pattern and State design pattern?

Viewed 90946

What are the differences between the Strategy design pattern and the State design pattern? I was going through quite a few articles on the web but could not make out the difference clearly.

Can someone please explain the difference in layman's terms?

21 Answers

This is a pretty old question, but still, I was also looking for the same answers and this is what I have discovered.

For State pattern lets consider an example of Medial Player Play button. When we do play it starts playing and makes the context aware that it is playing. Every time the client wants to perform play operation he checks the current state of the player. Now the client knows the state of the object is playing via the context object so he calls the pause state objects actions method. The part of the client realizing the state and on what state it needs to do action can be automated.

https://www.youtube.com/watch?v=e45RMc76884 https://www.tutorialspoint.com/design_pattern/state_pattern.htm

In the case of Strategy pattern, the arrangement of the class diagram is same as state pattern. The client comes to this arrangement to do some operation. That is instead of the different states there are different algorithms say for example different analysis that needs to be performed on the pattern. Here the clients tell the context what it wants to do that what algorithm (business defined custom algorithm) and then performs that.

https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm

Both implements open close principle so the developer has the capability to add new states to the state pattern and new algorithm.

But the difference is what they are used that is state pattern used to execute different logic based on a state of the object. And in a case of strategy different logic.

In short, with the strategy pattern we can set some behavior on the fly, with state pattern, we can be sure, that an object will change its behavior internally with the change of its state.

In my view, the main difference lies in their intentions. Technically, State and Strategy pattern look very similar. The main difference lies in:

  • The State pattern changes state of the context when it is required and state can be changed many times. So context changes its state or state can set another state
  • Strategy pattern sets strategy and strategy can be changed very rarely and context does not change its strategy.

Strategy pattern.

Our abstraction of some Sound strategies:

public interface ISound
{
    void Make();
}   
    

And its concrete strategies:

public class DogSoundStrategy : ISound
{
    public void Make()
    {
        Console.WriteLine("Bar");
    }
}

public class CatSoundStrategy : ISound
{
    public void Make()
    {
        Console.WriteLine("Meow");
    }
}

This is an abstraction of Animal who can make sound:

public abstract class Animal
{
    public void MakeSound(ISound sound)
    {
        sound.Make();
    }
}

And concrete animals look like this:

public class Dog : Animal
{
}

public class Cat : Animal
{   
}

And then we can call the above code like this:

Dog dog = new Dog();
dog.MakeSound(new DogSoundStrategy()); // there is a small chance 
    // that you want to change your strategy

Cat cat = new Cat();
cat.MakeSound(new CatSoundStrategy()); // there is a small chance 
    // that you want to change your strategy

There is a small chance that you want to change your strategy.

State pattern

Imagine you have a computer game where hero can be any super person in the world. Let's call him as Hero. He can run, swim and fly and change its shape to IronMan or SpiderMan. You have a button where you can change its shape or state to IronMan or SpiderMan.

The code of Hero would look like this:

public class Hero
{
    IState _state;

    public Hero()
    {
        _state = new SpiderManState();
    }

    public void Run()
    {
        _state.Run();
    }

    public void Swim()
    {
        _state.Swim();
    }

    public void Fly()
    {
        _state.Fly();
    }

    public void ChangeShape()
    {
        _state = _state.SetShape();
    }
}

Interface of IState would look like this:

public interface IState
{
    void Run();

    void Swim();

    void Fly();

    IState SetShape();
}

And concrete states look like this:

public class SpiderManState : IState
{
    public void Fly()
    {
        Console.WriteLine("Spiderman is flying");
    }

    public void Run()
    {
        Console.WriteLine("Spiderman is running");
    }

    public void Swim()
    {
        Console.WriteLine("Spiderman is swimming");
    }

    public IState SetShape()
    {
        return new IronManState();
    }
}

and IronManState would look like this:

public class IronManState : IState
{
    public void Fly()
    {
        Console.WriteLine("IronMan is flying");
    }

    public void Run()
    {
        Console.WriteLine("IronMan is running");
    }

    public void Swim()
    {
        Console.WriteLine("IronMan is swimming");
    }

    public IState SetShape()
    {
        return new SpiderManState();
    }
}

And now by clicking button ChangeShape() of Hero class, you will be able to change State of hero from, e.g. SpiderMan to IronMan.

So State of Context (Hero) depends on and can be changed by its button ChangeShape. And it can occur many times.

There is a high chance that you want to change context's state.

State pattern is also can be considered as an alternative to replace many if — else statements in class.

When you have a project which can be divided into 2 tasks:

task 1: you can use one of two different algorithms to accomplish: alg1, alg2

task 2: you can use one of three different algorithms to accomplish: alg3, alg4, alg5

alg1 and alg2 are interchangeable; alg3, alg4 and alg5 are interchangeable.

Choosing which algorithm to perform in task 1 and task 2 depends on states:

state 1: you need alg1 in task 1 and alg3 in task 2

state 2: you need alg2 in task 1 and alg5 in task 2

You context can change state object from state 1 to state 2. Then your task would be accomplished by alg2 and alg5, instead of alg1 and alg3.

You can add more interchangeable algorithms for task 1 or task 2. This is strategy pattern.

You can have more states with different combination of algorithms in task 1 and task 2. State pattern allows you to switch from one state to another and perform different combination of algorithms.

'Strategy' is only an algorithm that you can change it in different circumstances upon your need, and it processes something for you. Ex. you can choose how compress a file. zip or rar ... in a method.

But 'State' CAN change all your object behaviour, when it changes, Even it can change other fields... that's why it has a reference to its owner. You should notice that changing an object field can change object behaviour at all. Ex. when you change State0 to State1 in obj, you change an integer to 10.. so when we call obj.f0() that do some calculation and use that integer, it affects the result.

Both of the patterns are used for changing the behavior of an object,

By design, the state pattern object has a single state and the behavior of an object is based on the implemented single state (Class) and its subclasses.

In contrast, the strategy doesn't have a single state, and the behavior of an object is determined by the implementation of the different strategy objects.

  1. In Strategy pattern while implementing searching , we can have multiple strategies of searching e.g NaiveStrategy(), KMPStrategy() or RabinKarp() Strategy. These are all independent and there are somewhat stable choices. And most important, strategies can't shift from one another. Only Context is able to change strategies.
  2. State Pattern on the other hand is based on concept of Finite-State Machines. The states can transition from one another. Here states are less stable as compared to the strategies. And one thing, each concrete state maintains a reference to context and hence is able to transition to another state.

So crux is that, in strategy only context can set the strategy while in case of state pattern states can perform transition to other states. Strategies are unaware of each other in Strategy Pattern. While States are not unaware of each other in State Pattern and allow transition as they maintain a reference to context object.

"Strategy makes these objects completely independent and unaware of each other. However, State doesn’t restrict dependencies between concrete states, letting them alter the state of the context at will."

Reference : https://refactoring.guru/design-patterns/strategy

Related