<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 狀態模式的定義與特點 狀態(State)模式的定義:對有狀態的對象(對象可能會根據不同的情況做出不同的行為),把復雜的“判斷邏輯”提取到不同的狀態對象中,允許狀態對象在其內部狀態發生改變時改變其行為。 **優點:** 1. 狀態模式將與特定狀態相關的行為局部化到一個狀態中,并且將不同狀態的行為分割開來,滿足“單一職責原則”。 2. 減少對象間的相互依賴。將不同的狀態引入獨立的對象中會使得狀態轉換變得更加明確,且減少對象間的相互依賴。 3. 避免if語句有利于程序的擴展。通過定義新的子類很容易地增加新的狀態和轉換。 **缺點:** 1. 增加系統的類與對象的個數。 2. 狀態模式的結構與實現都較為復雜,如果使用不當會導致程序結構和代碼的混亂。 ## **狀態模式的結構** 狀態模式把受環境改變的對象行為包裝在不同的狀態對象里,其意圖是讓一個對象在其內部狀態改變的時候,其行為也隨之改變。現在我們來分析其基本結構和實現方法。 ## **應用場景:** * 用于對象的不同功能的轉換 * 當一個對象的行為取決于它的狀態,并且它必須在運行時根據狀態改變它的行為時,就可以考慮使用狀態模式。 * 一個操作中含有龐大的分支結構,并且這些分支決定于對象的狀態時。 ## **模式的結構** 1. 環境(Context)角色:也稱為上下文,它定義了客戶感興趣的接口,維護一個當前狀態,并將與狀態相關的操作委托給當前狀態對象來處理。 2. 抽象狀態(State)角色:定義一個接口,用以封裝環境對象中的特定狀態所對應的行為。 3. 具體狀態(Concrete??? State)角色:實現抽象狀態所對應的行為。 其結構圖如圖所示 ![](https://img.kancloud.cn/58/a2/58a20e5abd0c583f85b5bcb5b21ca9d7_605x350.png) ``` //環境類 class Context { private $state; //定義環境類的初始狀態 public function __construct() { $this->state = new ConcreteStateA(); } //設置新狀態 public function setState(State $state) { $this->state = $state; } /** * 讀取狀態 * @return State */ public function getState() { return $this->state; } //對請求做處理 public function Handle() { $this->state->Handle($this); } } //抽象狀態類 abstract class State { abstract public function Handle(Context $context); } //具體狀態A類 class ConcreteStateA extends State { public function Handle(Context $context) { print_r("當前狀態是 A."); $context->setState(new ConcreteStateB()); } } //具體狀態B類 class ConcreteStateB extends State { public function Handle(Context $context) { print_r("當前狀態是 B."); $context->setState(new ConcreteStateA()); } } class Client { public static function main() { $context = new Context(); //創建環境 $context->Handle(); //處理請求 $context->Handle(); $context->Handle(); $context->Handle(); } } Client::main(); 結果: 當前狀態是 A.當前狀態是 B.當前狀態是 A.當前狀態是 B. ``` 不用狀態模式時用if判斷 ``` //環境類 class Context { private $state; //定義環境類的初始狀態 public function __construct() { $this->state = 1; } //設置新狀態 public function setState(int $state) { $this->state = $state; } /** * 讀取狀態 * @return State */ public function getState() { return $this->state; } //對請求做處理 public function Handle() { if ($this->state == 1) { echo "狀態A"; } else if ($this->state == 2) { echo "狀態B"; } } } ``` 例子: ``` //環境類 class ScoreContext { private $state; //AbstractState public function __construct() { $this->state = new LowState($this); } public function setState(AbstractState $state) { $this->state = $state; } /** * @return AbstractState */ public function getState() { return $this->state; } public function add(int $score) { $this->state->addScore($score); } } //抽象狀態類 abstract class AbstractState { protected $scoreContext; //環境 ScoreContext protected $stateName = ""; //狀態名 protected $score = 0; //分數 abstract public function checkState(); //檢查當前狀態 public function addScore(int $x) { //設置當前分數 $this->score += $x; echo "加上:".$x."分,\t當前分數:".$this->score."分,"; echo $this->score; //更具當前分數設置狀態 $this->checkState(); print_r("\t當前狀態:".$this->scoreContext->getState()->stateName."<br>"); } } //具體狀態類:不及格 注意這里的參數是ScoreContext而其他的是AbstractState class LowState extends AbstractState { public function __construct($h) { if ($h instanceof ScoreContext) { $this->scoreContext = $h; $this->stateName = "不及格"; $this->score = 0; }else if ($h instanceof AbstractState) { $this->scoreContext = $h->scoreContext; $this->stateName = "不及格"; $this->score = $h->score; } } public function checkState() { if ($this->score >= 90) { $this->scoreContext->setState(new HighState($this)); } else if ($this->score >= 60) { $this->scoreContext->setState(new MiddleState($this)); } } } //具體狀態類:中等 class MiddleState extends AbstractState { public function __construct(AbstractState $state) { $this->scoreContext = $state->scoreContext; $this->stateName = "中等"; $this->score = $state->score; } public function checkState() { if ($this->score < 60) { $this->scoreContext->setState(new LowState($this)); } else if ($this->score >= 90) { $this->scoreContext->setState(new HighState($this)); } } } //具體狀態類:優秀 class HighState extends AbstractState { public function __construct(AbstractState $state) { $this->scoreContext = $state->scoreContext; $this->stateName = "優秀"; $this->score = $state->score; } public function checkState() { if ($this->score < 60) { $this->scoreContext->setState(new LowState($this)); } else if ($this->score < 90) { $this->scoreContext->setState(new MiddleState($this)); } } } class ScoreStateTest { public static function main() { $coreContext = new ScoreContext(); print_r("學生成績狀態測試:<br>"); $coreContext->add(30); $coreContext->add(40); $coreContext->add(25); $coreContext->add(-15); $coreContext->add(-25); } } ScoreStateTest::main(); 結果 學生成績狀態測試: 加上:30分, 當前分數:30分,30 當前狀態:不及格 加上:40分, 當前分數:70分,70 當前狀態:中等 加上:25分, 當前分數:95分,95 當前狀態:優秀 加上:-15分, 當前分數:80分,80 當前狀態:中等 加上:-25分, 當前分數:55分,55 當前狀態:不及格 ``` 例子2: >[info] 未使用狀態模式 ``` abstract class ILift { //電梯的四個狀態 const OPENING_STATE = 1; //門敞狀態 const CLOSING_STATE = 2; //門閉狀態 const RUNNING_STATE = 3; //運行狀態 const STOPPING_STATE = 4; //停止狀態; //設置電梯的狀態 public abstract function setState($state); //首先電梯門開啟動作 public abstract function open(); //電梯門有開啟,那當然也就有關閉了 public abstract function close(); //電梯要能上能下,跑起來 public abstract function run(); //電梯還要能停下來 public abstract function stop(); } /** * 電梯的實現類 */ class Lift extends ILift { private $state; public function setState($state) { $this->state = $state; } //電梯門關閉 public function close() { //電梯在什么狀態下才能關閉 switch ($this->state) { case ILift::OPENING_STATE: //如果是則可以關門,同時修改電梯狀態 $this->setState(ILift::CLOSING_STATE); break; case ILift::CLOSING_STATE: //如果電梯就是關門狀態,則什么都不做 //do nothing; return ; break; case ILift::RUNNING_STATE: //如果是正在運行,門本來就是關閉的,也說明都不做 //do nothing; return ; break; case ILift::STOPPING_STATE: //如果是停止狀態,本也是關閉的,什么也不做 //do nothing; return ; break; } echo 'Lift colse <br>'; } //電梯門開啟 public function open() { //電梯在什么狀態才能開啟 switch($this->state){ case ILift::OPENING_STATE: //如果已經在門敞狀態,則什么都不做 //do nothing; return ; break; case ILift::CLOSING_STATE: //如是電梯時關閉狀態,則可以開啟 $this->setState(ILift::OPENING_STATE); break; case ILift::RUNNING_STATE: //正在運行狀態,則不能開門,什么都不做 //do nothing; return ; break; case ILift::STOPPING_STATE: //停止狀態,淡然要開門了 $this->setState(ILift::OPENING_STATE); break; } echo 'Lift open <br>'; } //電梯開始跑起來 public function run() { switch($this->state){ case ILift::OPENING_STATE: //如果已經在門敞狀態,則不你能運行,什么都不做 //do nothing; return ; break; case ILift::CLOSING_STATE: //如是電梯時關閉狀態,則可以運行 $this->setState(ILift::RUNNING_STATE); break; case ILift::RUNNING_STATE: //正在運行狀態,則什么都不做 //do nothing; return ; break; case ILift::STOPPING_STATE: //停止狀態,可以運行 $this->setState(ILift::RUNNING_STATE); } echo 'Lift run <br>'; } //電梯停止 public function stop() { switch($this->state){ case ILift::OPENING_STATE: //如果已經在門敞狀態,那肯定要先停下來的,什么都不做 //do nothing; return ; break; case ILift::CLOSING_STATE: //如是電梯時關閉狀態,則當然可以停止了 $this->setState(ILift::CLOSING_STATE); break; case ILift::RUNNING_STATE: //正在運行狀態,有運行當然那也就有停止了 $this->setState(ILift::CLOSING_STATE); break; case ILift::STOPPING_STATE: //停止狀態,什么都不做 //do nothing; return ; break; } echo 'Lift stop <br>'; } } class Client { public static function test() { $lift = new Lift(); //電梯的初始條件應該是停止狀態 $lift->setState(ILift::STOPPING_STATE); //首先是電梯門開啟,人進去 $lift->open(); //然后電梯門關閉 $lift->close(); //再然后,電梯跑起來,向上或者向下 $lift->run(); //最后到達目的地,電梯挺下來 $lift->stop(); } } Client::test(); ``` 【例3】用“狀態模式”設計一個多線程的狀態轉換程序。 分析:多線程存在 5 種狀態,分別為新建狀態、就緒狀態、運行狀態、阻塞狀態和死亡狀態,各個狀態當遇到相關方法調用或事件觸發時會轉換到其他狀態 ![](https://img.kancloud.cn/3b/c9/3bc9b23c3c175e27eafafbb01a67995a_609x164.png) 現在先定義一個抽象狀態類(TheadState),然后為圖 3 所示的每個狀態設計一個具體狀態類,它們是新建狀態(New)、就緒狀態(Runnable )、運行狀態(Running)、阻塞狀態(Blocked)和死亡狀態(Dead),每個狀態中有觸發它們轉變狀態的方法,環境類(ThreadContext)中先生成一個初始狀態(New),并提供相關觸發方法 ![](https://img.kancloud.cn/6b/bf/6bbf8dddc11ac2a62adcecf5841f8216_629x670.png) ``` //環境類 class ThreadContext { private $state;//ThreadState public function __construct() { $this->state=new _New(); } public function setState(ThreadState $state) { $this->state=$state; } /** * * @return ThreadState */ public function getState() { return $this->state; } //新建狀態 public function start() { $this->state->start($this); } //就緒狀態 獲取cpu時間 public function getCPU() { $this->state->getCPU($this);//Runnable } //運行狀態 suspend 阻塞 public function suspend() { $this->state->suspend($this);//Running } //運行狀態 結束 public function stop() { $this->state->stop($this);//Running } //阻塞狀態 恢復 public function resume() { $this->state->resume($this);//Blocked } } //抽象狀態類:線程狀態 abstract class ThreadState { protected $stateName=""; //狀態名 } //具體狀態類:新建狀態 class _New extends ThreadState { public function __construct() { $this->stateName="新建狀態"; print_r("當前線程處于:新建狀態."); } public function start(ThreadContext $hj) { print_r("調用start()方法-->"); if($this->stateName === "新建狀態"){ $hj->setState(new Runnable()); }else{ print_r("當前線程不是新建狀態,不能調用start()方法."); } } } //具體狀態類:就緒狀態 class Runnable extends ThreadState { public function __construct() { $this->stateName="就緒狀態"; print_r("當前線程處于:就緒狀態."); } public function getCPU(ThreadContext $hj) { print_r("獲得CPU時間-->"); if($this->stateName==="就緒狀態") { $hj->setState(new Running()); } else { print_r("當前線程不是就緒狀態,不能獲取CPU."); } } } //具體狀態類:運行狀態 class Running extends ThreadState { public function __construct() { $this->stateName="運行狀態"; print_r("當前線程處于:運行狀態."); } public function suspend(ThreadContext $hj) { print_r("調用suspend()方法-->"); if($this->stateName === "運行狀態") { $hj->setState(new Blocked()); } else { print_r("當前線程不是運行狀態,不能調用suspend()方法."); } } public function stop(ThreadContext $hj) { print_r("調用stop()方法-->"); if($this->stateName === "運行狀態") { $hj->setState(new Dead()); } else { print_r("當前線程不是運行狀態,不能調用stop()方法."); } } } //具體狀態類:阻塞狀態 class Blocked extends ThreadState { public function __construct() { $this->stateName="阻塞狀態"; print_r("當前線程處于:阻塞狀態."); } public function resume(ThreadContext $hj) { print_r("調用resume()方法-->"); if($this->stateName === "阻塞狀態") { $hj->setState(new Runnable()); } else { print_r("當前線程不是阻塞狀態,不能調用resume()方法."); } } } //具體狀態類:死亡狀態 class Dead extends ThreadState { public function __construct() { $this->stateName="死亡狀態"; print_r("當前線程處于:死亡狀態."); } } class ThreadStateTest { public static function main() { $context=new ThreadContext(); $context->start(); $context->getCPU(); $context->suspend(); $context->resume(); $context->getCPU(); $context->stop(); } ThreadStateTest::main(); 結果: 當前線程處于:新建狀態. 調用start()方法-->當前線程處于:就緒狀態. 獲得CPU時間-->當前線程處于:運行狀態. 調用suspend()方法-->當前線程處于:阻塞狀態. 調用resume()方法-->當前線程處于:就緒狀態. 獲得CPU時間-->當前線程處于:運行狀態. 調用stop()方法-->當前線程處于:死亡狀態. ``` ## **狀態模式的擴展** 在有些情況下,可能有多個環境對象需要共享一組狀態,這時需要引入享元模式,將這些具體狀態對象放在集合中供程序共享,其結構圖如圖所示 ![](https://img.kancloud.cn/04/c6/04c6541d9b75a8b91543c1f8b20d2c10_771x365.png) ``` //環境類 class ShareContext { private $state;//ShareState private $stateSet=array(); public function __construct() { $this->state=new ConcreteState1(); $this->stateSet["1"]=$this->state; $this->state=new ConcreteState2(); $this->stateSet["2"]=$this->state; $this->state=$this->getState("1"); } //設置新狀態 public function setState(ShareState $state) { $this->state=$state; } /** * 讀取狀態 * @param String $key [description] * @return ShareState */ public function getState(String $key) { $s=$this->stateSet[$key]; return $s; } //對請求做處理 public function Handle() { $this->state->Handle($this); } } //抽象狀態類 abstract class ShareState { public abstract function Handle(ShareContext $context); } //具體狀態1類 class ConcreteState1 extends ShareState { public function Handle(ShareContext $context) { print_r("當前狀態是: 狀態1"); $context->setState($context->getState("2")); } } //具體狀態2類 class ConcreteState2 extends ShareState { public function Handle(ShareContext $context) { print_r("當前狀態是: 狀態2"); $context->setState($context->getState("1")); } } class FlyweightStatePattern { public static function main() { $context=new ShareContext(); //創建環境 $context->Handle(); //處理請求 $context->Handle(); $context->Handle(); $context->Handle(); } } FlyweightStatePattern::main(); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看