状态模式

模式描述

当一个对象的内在状态改变时,允许改变其行为。

优点

  1. 状态转换是显示的;
  2. 特定状态的行为是耦合的;
  3. State 变量可以被共享;

缺点

  1. 会造成子类变多;

应用场景

  1. 状态不多,状态转移也简单,但触发状态后执行逻辑复杂;

  2. 一个对象的行为取决于它的状态,并且必须在运行时根据状态改变行为;

DATE CHANGELOG
2023年5月4日 初始化

UML 类图

classDiagram
class Context {
	request()
}

class State {
	<<interface>>
	handle()
}

class ConcreteStateA {
	handle()
}

class ConcreteStateB {
	handle()
}

Context o.. State
State <|.. ConcreteStateA
State <|.. ConcreteStateB

Context <-- Client

参与者

Context

  • 维护一个 ConcreteState 对象实例,定义为当前状态;
  • 定义一个方法,用来对状态进行转移;

State

  • 定义封装一个与特定状态有关的行为;

ConcreteState

  • State 接口的实现;

Client

客户端。

数据流

  • Client 只需要配置一个 Context,剩下的由 Context 中的方法驱动;
  • Context 和 ConcreteState 都可以决定状态的后继者,以及转换条件;

相关模式

  • 享元模式:解释了何时以及怎样共享状态对象
  • 单例模式:状态对象通常是单例的;

补充

  • 分支逻辑法用于实现简单状态机;
  • 查表法用于处理状态多,但业务简单的场景;通过二维数组来表示状态转移图,能极大地提高代码的可读性和可维护性;
  • 像游戏这种比较复杂的状态机,包含的状态比较多,我优先推荐使用查表法,而状态模式会引入非常多的状态类,会导致代码比较难维护。相反,像电商下单、外卖下单这种类型的状态机,它们的状态并不多,状态转移也比较简单,但事件触发执行的动作包含的业务逻辑可能会比较复杂,所以,更加推荐使用状态模式来实现。

示例代码

golang

java