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 dif
The difference simply lies in that they solve different problems:
The constructs for achieving these different goals are however very similar; both patterns are examples of composition with delegation.
Some observations on their advantages:
By using the State pattern the state-holding (context) class is relieved from knowledge of what state or type it is and what states or types that are available. This means that the class adheres to the open-closed design principle (OCP): the class is closed for changes in what states/types there are, but the states/types are open to extensions.
By using the Strategy pattern the algorithm-using (context) class is relieved from knowledge of how to perform a certain task (-- the "algorithm"). This case also creates an adherence to the OCP; the class is closed for changes regarding how to perform this task, but the design is very open to additions of other algorithms for solving this task.
This likely also improves the context class' adherence to the single responsibility principle (SRP). Further the algorithm becomes easily available for reuse by other classes.
Strategy represents objects that "do" something, with the same begin and end results, but internally using different methodologies. In that sense they are analogous to representing the implementation of a verb. The State pattern OTOH uses objects that "are" something - the state of an operation. While they can represent operations on that data as well, they are more analogous to representation of a noun than of a verb, and are tailored towards state machines.
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.
Strategy pattern is used when you have multiple algorithm for a specific task and client decides the actual implementation to be used at runtime.
UML diagram from wiki Strategy pattern article:
Key features:
Refer to this post for more info & real world examples:
Real World Example of the Strategy Pattern
State pattern allows an object to alter its behaviour when its internal state changes
UML diagram from wiki State pattern article:
If we have to change the behavior of an object based on its state, we can have a state variable in the Object and use if-else condition block to perform different actions based on the state. State pattern is used to provide a systematic and lose-coupled way to achieve this through Context and State implementations.
Refer to this journaldev article for more details.
Key differences from sourcemaking and journaldev articles:
As wikipedia says about State pattern:
The state pattern is a behavioral software design pattern that allows an object to alter its behavior when its internal state changes. This pattern is close to the concept of finite-state machines.
Let us talk about real world example, it is a steering wheel in automobile. Steering wheel can be replaced. We can set bigger or smaller steering wheel. It is not a rule, however, let us think that small steering wheel makes bigger angle of automobile front wheels, than bigger steering wheel.
So, we can conclude that our automobile behaves differently dependent on the steering tool we set. For example, if we set smaller steering wheel, our automobile will turn left or right faster.
Thus, automobile responds to the events such as TurnLeft()
or TurnRight()
. However, the angle of the automobile wheels which can be turned depending on the currently selected steering wheel. Let us try to code:
public interface ISteeringWheel
{
void TurnLeft();
void Straight();
void TurnRight();
}
public class BigSteeringWheel : ISteeringWheel
{
public void Straight()
{
Console.WriteLine("BigSteeringWheel is straight");
}
public void TurnLeft()
{
Console.WriteLine("BigSteeringWheel is turned left 10
degrees");
}
public void TurnRight()
{
Console.WriteLine("BigSteeringWheel is turned right 10
degrees");
}
}
public class SmallSteeringWheel : ISteeringWheel
{
public void Straight()
{
Console.WriteLine("SmallHandleBar is straight");
}
public void TurnLeft()
{
Console.WriteLine("SmallHandleBar is turned left
20 degrees");
}
public void TurnRight()
{
Console.WriteLine("SmallHandleBar is turned right 20
degrees");
}
}
and Automobile
class:
public class Automobile
{
public ISteeringWheel SteeringWheel { get; private set; }
public Automobile()
{
SteeringWheel = new BigSteeringWheel();
}
public void TurnLeft()
{
SteeringWheel.TurnLeft();
}
public void TurnRight()
{
SteeringWheel.TurnRight();
}
public void SetSteeringWheel(ISteeringWheel handleBar)
{
SteeringWheel = handleBar;
}
}
Strategy pattern:
Definition from the Wikipedia:
The strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.
Pay attention to words such as «family of algorithms to use». So let us imagine we have a real automobile and when a driver turns the steering wheel left, we want that our automobile will do the following actions:
So, the above two actions could be considered as «family algorithms to use». Let us code this example.
The Steering wheel algorithm:
public interface ISteeringWheel
{
void TurnLeft();
void Straight();
void TurnRight();
}
public class BigSteeringWheel : ISteeringWheel
{
public void Straight()
{
Console.WriteLine("BigSteeringWheel is straight");
}
public void TurnLeft()
{
Console.WriteLine("BigSteeringWheel is turned left
10 degrees");
}
public void TurnRight()
{
Console.WriteLine("BigSteeringWheel is turned right
10 degrees");
}
}
The turn signal algorithm:
public interface ITurnSignal
{
void TurnOnLeft();
void TurnOnRight();
}
public class OrangeTurnSignal : ITurnSignal
{
public void TurnOnLeft()
{
Console.WriteLine("Left OrangeTurnSignal is turned on");
}
public void TurnOnRight()
{
Console.WriteLine("Right OrangeTurnSignal is turned on");
}
}
And the automobile class:
public class Automobile
{
public ISteeringWheel SteeringWheel { get; private set; }
public ITurnSignal TurnSignal { get; private set; }
public Automobile()
{
SteeringWheel = new BigSteeringWheel();
TurnSignal = new OrangeTurnSignal();
}
public void TurnLeft()
{
SteeringWheel.TurnLeft();
TurnSignal.TurnOnLeft();
}
public void TurnRight()
{
SteeringWheel.TurnRight();
TurnSignal.TurnOnRight();
}
}
CONCLUSION:
The State pattern
and the Strategy pattern
look very similar to each other. However, there is a tiny difference that State pattern
has a single state and all behaviors such as «TurnLeft» and «TurnRight» are encapsulated in one class. On the other hand, Strategy pattern
does not have a single state, but it has many states such as «SteeringWheel» and «TurnSignal». These different behaviors are encapsulated using different strategy objects such as «SteeringWheel» and «TurnSignal» objects. Therefore, this is a main difference between State and Strategy pattern.
In addition, we can think of the Strategy pattern
as a nice alternative to subclassing. Inheritance gives to us a very tight coupling between classes and this coupling between classes is defined at compile time. However, Strategy pattern
uses composition that allows setting behavior at run time by composing with a different object.
State pattern
is also can be considered as an alternative to replace many if — else
statements in class.
getStatus()
method that will return different statuses based on the
state of the object, but the caller of the method doesn't have to be
coded differently to account for each potential state.