In order to make proper use of State and Strategy design Pattern in Core Java application, its important for a Java developer to clearly understand difference between them. Though both State and Strategy design patterns has similar structure, and both of them are based upon Open closed design principle, represents ‘O’ from SOLID design principles, they are totally different on there intent. Strategy design pattern in Java is used to encapsulate related set of algorithms to provide runtime flexibility to client. Client can choose any algorithm at runtime, without changing Context class, which uses Strategy object. Some of the popular example of Strategy pattern is writing code, which uses algorithms e.g. encryption, compression or sorting algorithm.
On the other hand, State design pattern allows an object to behave differently at different state. Since real world object often has state, and they behave differently at different state, e.g. a Vending Machine only vend items if it’s in hasCoin state, it will not vend until you put the coin on it. You can now clearly see the difference between Strategy and State pattern, there intent is different. State pattern helps object to manage state, while Strategy pattern allows client to choose different behaviour. Another difference, which is not easily visible is, who drives change in behaviour. In case of Strategy pattern, it’s client, which provides different strategy to Context, on State pattern, state transition is managed by Context or State itself. Also, if you are managing state transition in State object itself, it must hold reference of Context e.g. Vending Machine, so that it can call setState() method to change current state of Context. On the other hand, Strategy object never held reference of Context, it’s client which passes Strategy of there choice to Context. As difference between state and strategy pattern is one of the popular Java design pattern question on Interviews, In this Java design pattern article, we will take a closer look on this. We will explore some similarity and difference between Strategy and State design pattern in Java, which will help to improve your understanding on both of these patterns.
Similarities between State and Strategy Pattern
If you look at UML diagram of State and Strategy design Pattern, they both look very similar to each other. An object that uses State object to change its behaviour is known as Context object, similarly an Object which uses a Strategy object to alter its behaviour is referred as Context object. Remember client interact with Context object. In case of state pattern, context delegates method calls to state object, which is held in form of current object, while in case of strategy pattern, context uses Strategy object passed as parameter or provided at the time of creating Context object.
UML Diagram of State Pattern in Java
This UML diagram is for state design pattern, drawn for a classic problem of creating object oriented design of Vending Machine in Java. You can see that State of Vending Machine is represented using an interface, which further has implementation to represent concrete state. Each state also holds reference of Context object to make transition to another state due to action triggered by Context.
UML Diagram of Strategy Pattern in Java
This UML diagram is for strategy design pattern, implementing sorting functionality. Since there are many sorting algorithm, this design pattern lets client choose the algorithm while sorting objects. In fact, Java Collection framework make use of this pattern to implement
Collections.sort() method, which is used to sort objects in Java. Only difference is instead of allowing client to choose sorting algorithm, they allow them to specify comparison strategy by passing instance of Comparator or Comparable interface in Java.
Let’s see couple of more similarities between these two core Java design patterns :
- Both State and Strategy Pattern makes it easy to add new state and strategy, without affecting Context object, which uses them.
- Both of them, makes your code follow open closed design principle, i.e. your design will be open for extension but closed for modification. In case of State and Strategy pattern, Context object is closed for modification, introduction of new State or new Strategy, either you don’t need to to modify Context of other state, or minimal changes are required.
- Just like Context object is started with a initial state in State design Pattern, a Context object also has a default strategy in case of Strategy pattern in Java.
- State pattern wraps different behaviour in form of different State object, while Strategy pattern wraps different behaviour in form of different Strategy object.
- Both Strategy and State Patterns relies on sub classes to implement behaviour. Every concrete strategy extends from an Abstract Strategy, each State is sub class of interface or abstract class used to represent State.
Difference between Strategy and State Pattern in Java
So now we know that State and Strategy are similar in structure and there intent are different. Let’s revisit some of the key difference between these design patterns.
- Strategy Pattern encapsulate a set of related algorithms, and allow client to use interchangeable behaviours though composition and delegation at runtime, On the other hand State pattern helps a class to exhibit different behaviours in different state.
- Another difference between State and Strategy Patten is that, State encapsulate state of an Object, while Strategy Pattern encapsulate an algorithm or strategy. Since states are cohesively associated with object, it can not be reused, but by separating strategy or algorithm from it’s context, we can make them reusable.
- In State pattern, individual state can contain reference of Context, to implement state transitions, but Strategies doesn’t contain reference of Context, where they are used.
- Strategy implementations can be passed as parameter to there the Object which uses them e.g. Collections.sort() accepts a Comparator, which is a strategy. On the other hand state is part of context object itself, and over time, context object transitions from one State to other.
- Though both Strategy and State follows Open closed design principle, Strategy also follow Single Responsibility principle, Since every Strategy encapsulate individual algorithm, different strategies are independent to each other. A change in one strategy, doesn’t order a change in another strategy.
- One more theoretical difference between Strategy and State pattern is that former defines “How” part of an Object e.g. How a Sorting object sorts data, One the other hand State Pattern defines “what” and “when” part of Object e.g. What can an object, when it’s on certain state.
- Order of State transition is well defined in State pattern, there is no such requirement for Strategy pattern. Client is free to choose any Strategy implementation of his choice.
- Some of the common example of Strategy Pattern is to encapsulate algorithms e.g. sorting algorithms, encryption algorithm or compression algorithm. If you see, your code needs to use different kind of related algorithms, than think of using Strategy pattern. On the other hand, recognizing use of State design pattern is pretty easy, if you need to manage state and state transition, without lots of nested conditional statement, state pattern is the pattern to use.
- Last but one of the most important difference between State and Strategy pattern is that, change in Strategy is done by Client, but Change in State can be done by Context or State object itself.
That’s all on difference between State and Strategy Pattern in Java. As I said, they both look similar in there class and UML diagrams, both of them enforces Open Closed design principle and encapsulate behaviours. Use Strategy design pattern, to encapsulate algorithm or strategy, which is provided to Context at runtime, may be as parameter or composed object and use State pattern for managing state transitions in Java.
|Reference:||Difference between State and Strategy Design Pattern in Java from our JCG partner Javin Paul at the Javarevisited blog.|