概述
结构设计类似责任链模式,但是在各个状态进行遍历的过程中,更注重的是条件的判断,只有符合条件的状态才能正常匹配进行处理。条件不成功的会立即切换到下一个状态。
有限状态机
状态机一般指的是有限状态机(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();