Wednesday, March 27, 2024

Design Pattern: State Pattern

Chapters

State Pattern
This pattern promotes loose coupling of states and object(context) where states are belong. The object enacts states via an internal state, in other words, the object has a reference of the interface of the states. States implements an interface that declares their behaviors. Take a look at the example below:

public class ClientCode{

  public static void main(String[] args){
    State walkState = new WalkState();
    State runState = new RunState();
    
    Character character = new Character("Foxy");
    character.setState(runState);
    character.animate();
    
    character.setState(walkState);
    character.animate();
  }
}

/*
Assume classes below are in another package.
Then, assume State and Character classes are
public
*/

abstract class State{

  abstract void animate(String name);

}

class RunState extends State{
  
  public RunState(){}
  
  @Override
  void animate(String name){
    System.out.println(name + " animation is set to run.");
    System.out.println("Run animation is being animated.");
  }
}

class WalkState extends State{
  
  public WalkState(){}
  
  @Override
  void animate(String name){
    System.out.println(name + " animation is set to walk.");
    System.out.println("Walk animation is being animated.");
  }
}

class Character{
  private String name;
  private State state;
  
  public Character(String name){
    this.name = name;
  }
  
  public void setState(State state){
    this.state = state;
  }
  
  public void animate(){
    if(state == null)
      return;
    
    state.animate(name);
  }
}

Result
Foxy animation is set to run.
Run animation is being animated.
Foxy animation is set to walk.
Walk animation is being animated.
In the example above, 'Character' class is the context, 'State' is an interface and 'RunState' and 'WalkState' are concrete states that implements 'State'. 'setState' method is the one that sets the internal state that our context can exhibit. 'animate' method of 'Character' class enacts the state. As you can see from the example above, it's a possibility that we can create new states without modifying 'Character' class too much or no modification at all.