状态模式详解

发布于:2025-06-22 ⋅ 阅读:(17) ⋅ 点赞:(0)

概述

结构设计类似责任链模式,但是在各个状态进行遍历的过程中,更注重的是条件的判断,只有符合条件的状态才能正常匹配进行处理。条件不成功的会立即切换到下一个状态。

有限状态机

状态机一般指的是有限状态机(FSM:finite-state machine),又称为优先自动状态机(FSA:finite-state automaton)。

  • 状态(State)

    状态机的有限个状态,例如:门可以分为开启、关闭两种状态。

  • 转换条件/事件(Transition Condition / Event)

    触发状态机的事件。只有收到相应的事件触发相应条件时候,状态机才会进行状态的转换。

  • 转换(Transition)

    记录状态机进行状态转换的多个过程(指定事件可以转换到指定状态的关系,可以是多个关系,表示当前状态可以在触发不同事件后,可以转换到多个不同的其他状态),用来在事件触发时候进行状态转换。

  • 动作(Action)

    在进行状态切换完成后,要执行的动作。

状态机分类

根据状态机的写法,可以分为三种(主要应用在硬件电路):

  • 一段式:一段式状态机的缺点就是许多种逻辑糅合在一起,不易后期的维护。
  • 两段式:
  • 三段式:

根据状态机的输出是否与输入有关系,可以分为两种:

  • Mealy 状态机(不仅与当前状态有关,还取决于当前的输入事件)
  • Moore 状态机(只与当前状态有关,与当前输入无关)

类图

Context
- IState state;
+setState(IState)
+rqeust()
«interface»
IState
+void handle(Context)
StopState
+void handle(Context)
RunningState
+void handle(Context)

注意:类图种状态的公共接口只有一个 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();

网站公告

今日签到

点亮在社区的每一天
去签到