The State Pattern

http://www.technologyuk.net/computer-gaming/gaming-landmarks/super-mario-bros.shtml

The State Pattern changes an object’s behaviour depending on it’s current state and sets it using objects that implement a State interface.

It implements a state machine using OO principles.

In order to use the State Pattern it is important to know what a state machine is, as the state pattern uses this idea in order to change the state of the object.

A state machine can be thought of as something that has:

  1. an initial state
  2. some inputs that can change the state
  3. possible outputs that occur as a result of that change
  4. new states that may arise as a result of those inputs
  5. a possible final state.

A good example could be that of a video game player..

In order to create objects of state, a State interface should be introduced:

public interface State {
String releaseButton();
String pressButton();
}

The player would have a set of states that would implement the State interface. An example of this could be the following:

public class JumpingState implements State {
private final Player player;

public JumpingState(Player player) {
this.player = player;
}

@Override
public String releaseButton() {
player.setState(player.getOnGroundState());
return "You just jumped, but you're back on the ground";
}
}
public class OnGroundState implements State {
private final Player player;

public OnGroundState(Player player) {
this.player = player;
}

@Override
public String pressButton() {
player.setState(player.getInAirState());
return "You're in the air!";
}
}

The player class would then simply hold a state and have some sort of starting state:

public class Player {
private State state;

public Player() {
State state = new StartingState();
}

public void setState(State state){
this.state = state;
}

public State getState(){
return state;
}
}

This way if you had this:


Player player = new Player();

OnGroundState onGround = new OnGroundState();
onGround.pressButton(player);
  System.out.println(player.getState());


InAirState inAir = new InAirState();
inAir.releaseButton(player);
  System.out.println(player.getState());

It would result in the following:

=> "You're in the air!"
=> "You just jumped, but you're back on the ground"

So that is how the State Pattern works. It’s useful for separating responsibility of a class and so enforces the Single Responsibility Principle. It is more useful when you are aware of the number of states of an object can have and they are fairly restricted. This is because it may get unwieldily and confusing quite quickly when more states are added and interrelate. There are also a lot of changes that need to be made whenever a new state is added. So like most of the patterns, this one needs to be used with caution.

Some interesting reads related to this topic: