state mode


In the State Pattern, the behavior of a class changes based on its state. This type of design pattern is a behavioral pattern.

In the state pattern, we create objects that represent various states and a context object whose behavior changes as the state object changes.

Introduction

Intent: Allows an object to change its behavior when its internal state changes, making the object appear as if its class has been modified.

Main solution: The behavior of an object depends on its state (property), and its related behavior can be changed according to changes in its state.

When to use: The code contains a large number of conditional statements related to the state of the object.

How to solve: Abstract various specific status classes.

Key code: Usually there is only one method in the command mode interface. The state pattern interface has one or more methods. Moreover, the methods of the implementation class of the state pattern generally return a value or change the value of an instance variable. In other words, the state pattern is generally related to the state of the object. The methods of the implementing class have different functions, overriding the methods in the interface. Like command mode, state mode can also be used to eliminate conditional selection statements such as if...else.

Application examples: 1. When playing basketball, athletes can have normal, abnormal and supernormal states. 2. In Zeng Hou Yi’s Chime, ‘bell is an abstract interface’, ‘Zhong A’ and so on are concrete states, and ‘Zeng Hou Yi’s Chime’ is a specific environment (Context).

Advantages: 1. Encapsulates conversion rules. 2. Enumerate possible states. Before enumerating states, you need to determine the state type. 3. Put all the behaviors related to a certain state into a class, and you can easily add new states. You only need to change the object state to change the object's behavior. 4. Allow the state transition logic to be integrated with the state object instead of a huge conditional statement block. 5. Multiple environment objects can share a state object, thereby reducing the number of objects in the system.

Disadvantages: 1. The use of state mode will inevitably increase the number of system classes and objects. 2. The structure and implementation of the state mode are relatively complex. If used improperly, it will lead to confusion in the program structure and code. 3. The state mode does not support the "opening and closing principle" very well. For the state mode that can switch states, adding a new state class requires modifying the source code responsible for state conversion. Otherwise, it cannot switch to the new state, and the modification The behavior of a certain state class also requires modification of the source code of the corresponding class.

Usage scenarios: 1. Scenarios where behavior changes as the state changes. 2. Replacement of conditional and branch statements.

Note: Use the state mode when the behavior is constrained by the state, and there are no more than 5 states.

Implementation

We will create a State interface and an entity state class that implements the State interface. Context is a class with a certain state.

StatePatternDemo, our demo class uses Context and state objects to demonstrate the behavior changes of Context when the state changes.

state_pattern_uml_diagram.jpg

Step 1

Create an interface.

State.java

public interface State {
   public void doAction(Context context);
}

Step 2

Create an entity class that implements the interface.

StartState.java

public class StartState implements State {

   public void doAction(Context context) {
      System.out.println("Player is in start state");
      context.setState(this);	
   }

   public String toString(){
      return "Start State";
   }
}

StopState.java

public class StopState implements State {

   public void doAction(Context context) {
      System.out.println("Player is in stop state");
      context.setState(this);	
   }

   public String toString(){
      return "Stop State";
   }
}

Step 3

Create Context class.

Context.java

public class Context {
   private State state;

   public Context(){
      state = null;
   }

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

   public State getState(){
      return state;
   }
}

Step 4

Use Context to see when the state State changes behavioral changes over time.

StatePatternDemo.java

public class StatePatternDemo {
   public static void main(String[] args) {
      Context context = new Context();

      StartState startState = new StartState();
      startState.doAction(context);

      System.out.println(context.getState().toString());

      StopState stopState = new StopState();
      stopState.doAction(context);

      System.out.println(context.getState().toString());
   }
}

Step 5

Verify the output.

Player is in start state
Start State
Player is in stop state
Stop State