狀態模式是一種行為型模式,它允許一個物件在其內部狀態改變時改變它的行為。物件看起來似乎修改了它的類,狀態模式變化的位置在於物件的狀態。
主要角色
抽象狀態(State)角色:定義一個接口,用以封裝環境對象的一個特定的狀態所對應的行為
具體狀態(ConcreteState)角色:每一個具體狀態類都實現了環境( Context)的一個狀態所對應的行為
環境(Context)角色:定義客戶端所感興趣的接口,並且保留一個具體狀態類別的實例。這個特定狀態類別的實例給出此環境物件的現有狀態
適用性
一個物件的行為取決於它的狀態,並且它必須在運行時刻根據狀態改變它的行為
一個操作中含有龐大的多分支的條件語句,且這些分支依賴於該物件的狀態。這個狀態通常用一個或多個枚舉常數來表示。通常,有多個操作包含這一相同的條件結構。 State模式模式將每一個條件分支放入獨立的類別中。這使得你可以要所對象自身的情況將對象的狀態作為一個對象,這一對象可以不依賴於其他對象而獨立變化
類圖
優點
<?php interface State { // 抽象状态角色 public function handle(Context $context); // 方法示例 } class ConcreteStateA implements State { // 具体状态角色A private static $_instance = null; private function __construct() {} public static function getInstance() { // 静态工厂方法,返还此类的唯一实例 if (is_null(self::$_instance)) { self::$_instance = new ConcreteStateA(); } return self::$_instance; } public function handle(Context $context) { $context->setState(ConcreteStateB::getInstance()); } } class ConcreteStateB implements State { // 具体状态角色B private static $_instance = null; private function __construct() {} public static function getInstance() { if (is_null(self::$_instance)) { self::$_instance = new ConcreteStateB(); } return self::$_instance; } public function handle(Context $context) { $context->setState(ConcreteStateA::getInstance()); } } class Context { // 环境角色 private $_state; public function __construct() { // 默认为stateA $this->_state = ConcreteStateA::getInstance(); } public function setState(State $state) { $this->_state = $state; } public function request() { $this->_state->handle($this); } } // client $context = new Context(); $context->request(); $context->request(); $context->request(); $context->request(); ?>
優缺點
優點它將與特定狀態相關的行為局部化它使得狀態轉換顯示化State物件可被共享