状态模式详解
概述
结构设计类似责任链模式,但是在各个状态进行遍历的过程中,更注重的是条件的判断,只有符合条件的状态才能正常匹配进行处理。条件不成功的会立即切换到下一个状态。
有限状态机
状态机一般指的是有限状态机(FSM:finite-state machine),又称为优先自动状态机(FSA:finite-state automaton)。
-
状态(State)
状态机的有限个状态,例如:门可以分为开启、关闭两种状态。
-
转换条件/事件(Transition Condition / Event)
触发状态机的事件。只有收到相应的事件触发相应条件时候,状态机才会进行状态的转换。
-
转换(Transition)
记录状态机进行状态转换的多个过程(指定事件可以转换到指定状态的关系,可以是多个关系,表示当前状态可以在触发不同事件后,可以转换到多个不同的其他状态),用来在事件触发时候进行状态转换。
-
动作(Action)
在进行状态切换完成后,要执行的动作。
状态机分类
根据状态机的写法,可以分为三种(主要应用在硬件电路):
- 一段式:一段式状态机的缺点就是许多种逻辑糅合在一起,不易后期的维护。
- 两段式:
- 三段式:
根据状态机的输出是否与输入有关系,可以分为两种:
- Mealy 状态机(不仅与当前状态有关,还取决于当前的输入事件)
- Moore 状态机(只与当前状态有关,与当前输入无关)
类图
注意:
类图种状态的公共接口只有一个 handle(Context),实际使用时候状态一般都不止一个接口,可能有若干个
关键代码
class Context {private $state;public function __construct() {$this->state = new StopState();}public function setState(IState $state) {$this->state = state;}public function request() {$this->state->handle($this);}
}interface IState {public function handle(Context $context);
}class StopState implements IState {public function handle(Context $context) {// 与其他状态条件不同.if (...) {echo "stop state ...". PHP_EOL; } else {$context->setSate(new RunningState());$context->request();}}
}class RunningState implements IState {public function handle(Context $context) {// 与其他状态不同的条件if (...) {echo "stop state ...". PHP_EOL; } else {$context->setSate(new RunningState());$context->request();}}
}
// 客户端代码.
$context = new Context();
$context->request();