Design Difference Between State Design Pattern and Strategy Design Pattern

Naveen kulkarni
Javarevisited
Published in
4 min readMar 6, 2019

We all know that State and Strategy Patterns are categorized under Behavioral Design Patterns. Where object remains the same but Behavior alters depending on context and type of operations. Now, Let us understand both of these design patterns and their Micro Biological differences.

State Pattern: State pattern is used when an object changes its behavior depending on the internal state. It is a clean way of an Object to partially change its type or behavior at run-time.

Strategy Pattern: Strategy Pattern is also called as Policy Pattern. It’s used when there are multiple algorithms or calculations for a specific object and context implementations are decided at run-time.

Strategy

Differences between both Design patterns with a Real-Time Use Case.

Let us take the Life Cycle of a Human Being as an example.

We all know when we grow older every year. We come across many states in life with which we perform different tasks in each state.

Let us have the various states for our example as

  1. Infants(0–2 years)
  2. Baby(2–5 years)
  3. Boy(5–14 years)
  4. Teenager(14–18 years)
  5. Youth(18–28 years)
  6. Adult(28–60 years)
  7. Senior Citizen(60–80 years)
  8. Super Senior Citizen(80 Years and Above)

Let us have various Task to perform as

  1. Vaccination
  2. Day Care
  3. Toys
  4. Sports
  5. Play School
  6. School
  7. Graduation
  8. Marriage
  9. Holidays

Now, as we have identified States and Tasks that need to be performed. We can easily differentiate between State and Strategy Pattern in a simple diagram as shown below.

Implementation of Strategy Pattern used to calculate Expenses of a Person on Runtime.

ApplicationRun.java, used to act as an entry point of application.

package org.nbk.designpattern.behavioural.strategy.example;public class ApplicationRun {public static void main(String[] args) {
LifeCycleStrategy lifeCycleStrategy = new Infant();
LifeCycleStrategyContext lifeCycleStrategyContext = new LifeCycleStrategyContext(lifeCycleStrategy);
lifeCycleStrategyContext.getExpenses();
}
}

We create an interface LifeCycleStrategy.java, which has the common behaviors of each LifeCycle of a person.

package org.nbk.designpattern.behavioural.strategy.example;public interface LifeCycleStrategy {
public void getExpenses();
}

We create a context Class LifeCycleStrategyContext.java which is an aggregation of our LifeCycleStrategy interface. This class will help in injecting the type of AgeCategory to be used to calculate Expenses.

package org.nbk.designpattern.behavioural.strategy.example;public class LifeCycleStrategyContext {

private LifeCycleStrategy lifeCycleStrategy;

public LifeCycleStrategyContext(LifeCycleStrategy lifeCycleStrategy){
this.lifeCycleStrategy = lifeCycleStrategy;
}

public void getExpenses() {
lifeCycleStrategy.getExpenses();
}
}

Finally, We have a concrete class which will help us to get the expense. In our example, I want to calculate the expense of an Infant.

Infant.java implements LifeCycleStrategy.java interface, to get all common behaviors of Infant’s lifeCycle.

package org.nbk.designpattern.behavioural.strategy.example;public class Infant implements LifeCycleStrategy {@Override
public void getExpenses() {
System.out.println(" Expenses of Infants");
System.out.println(" 1. Vaccination");
System.out.println(" 2. Day Care");
}
}

Implementation of State Design Pattern to get LifeCycle of a AgeCategory groups.

ApplicationRun.java used to act as an entry point of application.

package org.nbk.designpattern.behavioural.state.example;public class ApplicationRun {public static void main(String[] args) {LifeCycleState lifeCycleState = new Infant();
LifeCycleStateContext lifeCycleStateContext = new LifeCycleStateContext();
lifeCycleStateContext.setLifeCycleState(lifeCycleState);
lifeCycleStateContext.getLifeCycle();
}
}

We create an interface LifeCycleState.java which has common behavior to identify lifeCycle.

package org.nbk.designpattern.behavioural.state.example;public interface LifeCycleState {
public void getLifeCycle(LifeCycleStateContext ctx);
}

We create a StateContext Class called LifeCycleStateContext.java. The context class is aggregated with LifeCycleState interface. Context sets the type of LifeCycle at Runtime using a constructor. The getLifeCycle method helps to get lifeCycle of a concrete LifeCycleState.

package org.nbk.designpattern.behavioural.state.example;public class LifeCycleStateContext {private LifeCycleState lifeCycleState;public LifeCycleStateContext() {}public void setLifeCycleState(LifeCycleState lifeCycleState) {
this.lifeCycleState = lifeCycleState;
}
public LifeCycleStateContext(LifeCycleState lifeCycleState) {
this.lifeCycleState = lifeCycleState;
}
public LifeCycleState getLifeCycleState() {
return lifeCycleState;
}
public void getLifeCycle() {
lifeCycleState.getLifeCycle(this);
}
}

Finally, We have Infant Concrete class Infant.java, which implements our LifeCycleState.java interface to get lifeCycle of context defined.

package org.nbk.designpattern.behavioural.state.example;public class Infant implements LifeCycleState{@Override
public void getLifeCycle(LifeCycleStateContext ctx) {
System.out.println("I am an Infant");
}
}

State Pattern Vs Strategy Pattern

Both patterns are similar, but the idea among these patterns are slightly different.

Strategy Patterns defines a family of interchangeable algorithms i.e the pattern is used on bases of any kind of calculations or algorithms. Whereas, in State Pattern the behavior completely changes based on actual state.

In the Strategy Pattern, the client should be aware of the type of strategies to be used and changed explicitly. Whereas, each state is linked to one after another to create a flow as defined in a finite state Machine in State Pattern.

Conclusion

State Pattern: It is great when a developer wants to avoid primitive if/else statements. Instead of, extracting logic to separate classes and let our context object delegate the behavior to the methods implemented in-state class. Besides, we can leverage transitions between the states, where one state can alter the state of the context.

Strategy Pattern: It is great when we have multiple ways to perform the same task (in software language when we have multiple algorithms to perform the same operation), we should consider implementing the Strategy pattern. By using this pattern, we are free to add/remove an algorithm because switching of these algorithms is not transparent to the application.

--

--