State Pattern

In the State Pattern, a class's behavior changes based on its state. This type of design pattern belongs to behavioral patterns.

In the State Pattern, we create objects representing various states and a context object whose behavior changes as the state object changes.

The state pattern allows an object to change its behavior when its internal state changes, so that the object exhibits different behaviors in different states. By encapsulating each state as an independent class, it avoids using a large number of conditional statements to implement state switching.

Introduction

intent

It allows an object to alter its behavior when its internal state changes, appearing as if the object changed its class.

Main problems solved

  • The state pattern solves the problem of object behavior depending on its state, allowing the object to switch behaviors when the state changes.

Use Case

  • Use it when there are many conditional statements in the code, and these conditional statements depend on the object's state.

Implementation Approach

  • Define the state interface: Declares one or more methods to encapsulate the behavior of a specific state.
  • Create concrete state classes: Implements the state interface and implements specific behaviors based on different states.
  • Define the context class: Contains a reference to a state object and updates its behavior when the state changes.

Key code

  • State Interface: Declares behavior methods.
  • Concrete state class: Implements the state interface and encapsulates specific behavior.
  • Context Class: Maintains a state object and provides methods to change its state.

Application example

  • Basketball player state: An athlete can have states such as normal, abnormal, and exceptional.
  • Marquis Yi of Zeng's chime bells: Chime bells serve as the context, and different bells (states) produce different performance effects.

Advantages

  • Encapsulates state transition rules: Encapsulates state transition logic within state objects.
  • Easy to Extend: Adding new state classes does not affect existing code.
  • Centralize state-related behavior: Concentrates all behavior related to a specific state into one class.
  • Simplify conditional statements: Avoids using a large number of conditional statements to switch behaviors.
  • State Sharing: Allows multiple context objects to share the same state object.

Disadvantages

  • Increases the number of classes and objects: Each state requires a concrete state class.
  • Complex Implementation: The pattern structure and implementation are relatively complex.
  • Insufficient support for the open-closed principle: Adding new states or modifying state behavior may require changes to existing code.

Usage suggestions

  • When an object's behavior changes with its state, consider using the State Pattern.
  • The State Pattern is suitable for replacing complex conditional or branch statements.

Notes

  • The State Pattern is suitable when the number of states is limited (usually no more than 5).
  • Use with caution to avoid making the system overly complex.

Structure

The State Pattern includes the following main roles:

  • Context: Defines the interface that clients are interested in and maintains a reference to the current state object. The context can delegate state-related behavior processing to the state object.

  • State: Defines an interface for encapsulating the behavior of a state related to the context.

  • Concrete State: Implements the state interface and is responsible for handling behavior related to that state. A concrete state object usually maintains a reference to the context object internally, so that it can switch to different states based on different conditions.

Implementation

We will create aStateInterface and implementationStateThe entity state class of the interface.ContextA class with a certain state.

StatePatternDemo, our demo class usesContextand state objects to demonstrate Context's behavior changes when its state changes.

状态模式的 UML 图

Step 1

Create an interface.

State.java

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

Step 2

Create entity classes that implement 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

CreateContextclass.

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

UsageContextTo view when the stateStateBehavior changes when the state changes.

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

Run the program, output result:

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

More Articles

other extensions