The State pattern is primarily used when you need to change the behavior on an object based upon the state that it’s in t run-time. For example vending machine has a different sates and can do specific actions based on those states.

Code example:
public class VendingMachine {
public VendingMachine(int count) {
...
}
//Handle User Events
public void InsertDollar(){
...
}
public void EjectMoney(){
...
}
public void Dispense(){
...
}
}
Custom Implementation:
State:
sealed class State { //Singleton objects for states
private State();
//all potential vending machine states as singletons
public sealed static State Idle = new State();
public sealed static State HasOneDollar = new State();
public sealed static State OutOfStock = new State();
}
Vending Machine:
public class VendingMachine {
private State currentState;
private int count;
public VendingMachine(int count) {
if {count > 0){
currentState = State.Idle;
this.count = count;
}
else {
currentState = State.OutOfStock;
this.count = 0;
}
}
}
Insert Dollar trigger:
public void InsertDollar() {
if (currentState == State.Idle) {
currentState = State.HasOneDollar;
}
else if (currentState == State.HasOneDollar) {
doReturnMoney();
currentState = State.Idle;
}
else if (currentState == State.OutOfStock) {
doReturnMoney();
}
}
The proper implementation:
This code looks massive, but how it should look better with the proper implementation of the State Design pattern? Firstly, we have to define a state interface with a method for each trigger that a state needs to respond to.
%20Class%20Diagram.png?raw=true)
public interface State {
public void InsertDollar(VendingMachine vendingMachine);
public void EdjectMoney(VendingMachine vendingMachine);
public void Dispense(VendingMachine vendingMachine);
}
Now we have to implement each state, for example Idle State will look like this:
public class IdleState: IState {
public void InsertDollar(VendingMachine vendingMachine){
Console.WriteLine("Dollar inserted");
vendingMachine.SetState(vendingMachine.GetHasOneDollarState());
}
public void EjectMoney(VendingMachine vendingMachine) {
Console.WriteLine("No money to return");
}
public void Dispense(VendingMachine vendingMachine) {
Console.WriteLine("Payment required");
}
}
public class HasOneDollarState: IState {
public void InsertDollar(VendingMachine vendingMachine){
Console.WriteLine("Already have one dollar");
vendingMachine.DoReturnMoney();
vendingMachine.SetState(vendingMachine.GetIdleState());
}
public void EjectMoney(VendingMachine vendingMachine) {
Console.WriteLine("Returning Money");
vendingMachine.DoReturnMoney();
vendingMachine.SetState(vendingMachine.GetIdleState());
}
public void Dispense(VendingMachine vendingMachine) {
Console.WriteLine("Releasing product");
if (vendingMachine.GetCount() > 1) {
vendingMachine.DoReleaseProduct();
vendingMachine.SetState(vendingMachine.GetIdleState());
}
else {
vendingMachine.DoReleaseProduct();
vendingMachine.SetState(vendingMachine.GetOutOfStockState());
}
}
}
public class VendingMachine {
private State idleState;
private State hasOneDollarState;
private State outOfStockState;
private State currentState;
private int count;
public VendingMachine(int count){
// make the needed states
idleState = new IdleState();
hasOneDollarState = new HasOneDollarState();
outOfStockState = new OutOfStockState();
if(count > 0) {
currentState = idleState;
this.count = count;
}
else {
currentState = outOfStockState;
this.count = 0;
}
}
//Delegates to states
public void InsertDollar(){
currentState.InsertDollar(this);
}
public void EjectMoney(){
currentState.EjectMoney(this);
}
public void Dispense(){
currentState.Dispense(this);
}
}
The structure of the State pattern:

One thought on “State Pattern”