概述
結構設計類似責任鏈模式,但是在各個狀態進行遍歷的過程中,更注重的是條件的判斷,只有符合條件的狀態才能正常匹配進行處理。條件不成功的會立即切換到下一個狀態。
有限狀態機
狀態機一般指的是有限狀態機(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();