今回はPHPステータスモードの使い方について詳しく解説します。PHPステータスモードを使用する際の注意点は何ですか?実際の事例を見てみましょう。
状態設計パターンとは何ですか
を使用すると、オブジェクトの固有の状態が変化したときにその動作を変更し、オブジェクトがそのクラスを変更したかのように見せることができます。
状態パターンは主に、オブジェクトの状態を制御する条件式が複雑すぎる場合の状況を解決します。状態判定ロジックを異なる状態を表す一連のクラスに移すことで、複雑な判定ロジックを簡素化できます。
状態パターンを使用する場合
オブジェクトの頻繁な変更は、条件ステートメントに大きく依存します。 条件文 (switch 文や else 句を含む文など) 自体には何も問題はありませんが、オプションが多すぎると、プログラムが混乱し始めたり、オプションの追加や変更に時間がかかりすぎたりします。それが負担になり、問題が発生します
状態の設計パターンの場合、各状態にはパブリック インターフェイスを実装する独自の具体的なクラスがあります。オブジェクトの制御フローを確認する必要はありませんが、それについて考えてみましょう。別の角度、つまりオブジェクトの状態から見たものです。
ステートマシンは、さまざまな状態、ある状態から別の状態への遷移、および状態を変化させるトリガーに焦点を当てたモデルです。照明の点灯と消灯を例にすると、状態モデル 本質は3点に分かれます:
①状態(消灯と点灯)②遷移(消灯から点灯、点灯から消灯)③トリガー(ライトスイッチ)
つまり、状態パターンでは、参加者がオブジェクトの状態を追跡する必要があります。ライトを例にとると、ライトは現在の状態を知る必要があります
例: ライトをオンまたはオフにします。 Light.php
<?php class Light { private $offState; //关闭状态 private $onState; //开启状态 private $currentState; //当前状态 public function construct() { $this->offState = new OffState($this); $this->onState = new OnState($this); //开始状态为关闭状态Off $this->currentState = $this->offState; } //调用状态方法触发器 public function turnLightOn() { $this->currentState->turnLightOn(); } public function turnLightOff() { $this->currentState->turnLightOff(); } //设置当前状态 public function setState(IState $state) { $this->currentState = $state; } //获取状态 public function getOnState() { return $this->onState; } public function getOffState() { return $this->offState; } }
in
コンストラクター で、Light は IState 実装の 2 つのインスタンスをインスタンス化します。1 つはオフに対応し、もう 1 つはオンに対応します。$this->offState = new OffState($this);
$this->onState = new OnState($this);
このインスタンス化プロセスは、自己と呼ばれる一種の再帰を使用します。 Referral
コンストラクターの実際のパラメーター
関数パラメーターは、Light クラス自体への参照として記述されます。状態クラスは、パラメーターとして Light クラスのインスタンスを受け取ることを望んでいます。setState メソッドは、 state オブジェクトをパラメータとして使用し、現在の状態を設定します。実際のパラメータは、状態がトリガーされると、現在の状態を指定して Light クラスに情報を送信します。このインターフェイスの php
<?php interface IState { public function turnLightOn(); public function turnLightOff(); }実装クラス
OnState.php
<?php class OnState implements IState { private $light; public function construct(Light $light) { $this->light = $light; } public function turnLightOn() { echo "灯已经打开了->不做操作<br />"; } public function turnLightOff() { echo "灯关闭!看不见帅哥chenqionghe了!<br />"; $this->light->setState($this->light->getOffState()); } }
OffState.php
<?php class OffState implements IState { private $light; public function construct(Light $light) { $this->light = $light; } public function turnLightOn() { echo "灯打开!可以看见帅哥chenqionghe了!<br />"; $this->light->setState($this->light->getOnState()); } public function turnLightOff() { echo "灯已经关闭了->不做操作<br />"; } }デフォルトの状態は、IState メソッドのturnLightOn およびturnLightOff を実装する必要があります。Light は、turnLightOn メソッドを呼び出します。これは (ライトが点灯しています! イケメンの陳瓊河が見えます) と表示され、その後 OnState 現在の状態に設定されます。 ただし、OffState の TurnLightOff メソッドが呼び出された場合は、リマインダー ライトのみがオフになり、他のアクションは行われません。
クライアントからのすべてのリクエスト
クライアントは、Light、Client、および任意の状態を通じて発行されます。IState インターフェイスを含む、クラス間に直接の接続はありません。以下のクライアントは、両方のメソッドをトリガーするリクエストを示しています。Client.php
<?php function autoload($class_name) { include_once $class_name.'.php'; } class Client { private $light; public function construct() { $this->light = new Light(); $this->light->turnLightOn(); $this->light->turnLightOn(); $this->light->turnLightOff(); $this->light->turnLightOff(); } } $worker = new Client();
状態の追加
すべてのデザイン パターンにおいて、非常に重要な点は、他のパターンと同様に、状態パターンも簡単に変更できることです。ライトの例にさらに 2 つの状態を追加してみましょう。brighter (Brighter) と Brightest は 4 つの状態になり、シーケンスは「off」状態から「on」状態にのみ変更できます。オン状態からオフ状態に変更することはできません。オン状態は「より明るい」状態と「最も明るい」状態にのみ変更できます。インターフェースを変更します
。最初に変更するのはインターフェイス IState です。対応するメソッドをこのインターフェイスで指定する必要があります。これは、より明るい状態と最も明るい状態に移行するために使用できます。
IState.php
<?php interface IState { public function turnLightOn(); public function turnLightOff(); public function turnBrighter(); public function turnBrightest(); }
现在所有状态类都必须包含这4个方法, 它们都需要结合到Light类中.
改变状态
状态设计模式中有改变时, 这些新增的改变会对模式整体的其他方面带来影响. 不过, 增加改变相当简单, 每个状态只有一个特定的变迁.
四个状态
OnState.php
<?php class OnState implements IState { private $light; public function construct(Light $light) { $this->light = $light; } public function turnLightOn() { echo "不合法的操作!<br />"; } public function turnLightOff() { echo "灯关闭!看不见帅哥chenqionghe了!<br />"; $this->light->setState($this->light->getOffState()); } public function turnBrighter() { echo "灯更亮了, 看帅哥chenqionghe看得更真切了!<br />"; $this->light->setState($this->light->getBrighterState()); } public function turnBrightest() { echo "不合法的操作!<br />"; } }
OffState.php
<?php class OffState implements IState { private $light; public function construct(Light $light) { $this->light = $light; } public function turnLightOn() { echo "灯打开!可以看见帅哥chenqionghe了!<br />"; $this->light->setState($this->light->getOnState()); } public function turnLightOff() { echo "不合法的操作!<br />"; } public function turnBrighter() { echo "不合法的操作!<br />"; } public function turnBrightest() { echo "不合法的操作!<br />"; } }
Brighter.php
<?php class BrighterState implements IState { private $light; public function construct(Light $light) { $this->light = $light; } public function turnLightOn() { echo "不合法的操作!<br />"; } public function turnLightOff() { echo "不合法的操作!<br />"; } public function turnBrighter() { echo "不合法的操作!<br />"; } public function turnBrightest() { echo "灯最亮了, 看帅哥chenqionghe已经帅到无敌!<br />"; $this->light->setState($this->light->getBrightestState()); } }
Brightest.php
<?php class BrightestState implements IState { private $light; public function construct(Light $light) { $this->light = $light; } public function turnLightOn() { echo "灯已经打开了->不做操作<br />"; } public function turnLightOff() { echo "灯关闭!看不见帅哥chenqionghe了!<br />"; $this->light->setState($this->light->getOffState()); } public function turnBrighter() { echo "不合法的操作!<br />"; } public function turnBrightest() { echo "不合法的操作!<br />"; } }
更新Light类
Light.php
<?php class Light { private $offState; //关闭状态 private $onState; //开启状态 private $brighterState; //更亮状态 private $brightestState;//最亮状态 private $currentState; //当前状态 public function construct() { $this->offState = new OffState($this); $this->onState = new OnState($this); $this->brighterState = new BrighterState($this); $this->brightestState = new BrightestState($this); //开始状态为关闭状态Off $this->currentState = $this->offState; } //调用状态方法触发器 public function turnLightOn() { $this->currentState->turnLightOn(); } public function turnLightOff() { $this->currentState->turnLightOff(); } public function turnLightBrighter() { $this->currentState->turnBrighter(); } public function turnLigthBrightest() { $this->currentState->turnBrightest(); } //设置当前状态 public function setState(IState $state) { $this->currentState = $state; } //获取状态 public function getOnState() { return $this->onState; } public function getOffState() { return $this->offState; } public function getBrighterState() { return $this->brighterState; } public function getBrightestState() { return $this->brightestState; } }
更新客户
<?php function autoload($class_name) { include_once $class_name.'.php'; } class Client { private $light; public function construct() { $this->light = new Light(); $this->light->turnLightOn(); $this->light->turnLightBrighter(); $this->light->turnLigthBrightest(); $this->light->turnLightOff(); $this->light->turnLigthBrightest(); } } $worker = new Client();
运行结果如下
灯打开!可以看见帅哥chenqionghe了!
灯更亮了, 看帅哥chenqionghe看得更真切了!
灯最亮了, 看帅哥chenqionghe已经帅到无敌!
灯关闭!看不见帅哥chenqionghe了!
不合法的操作!
九宫格移动示例
九宫格的移动分为4个移动:
上(Up)
下(Down)
左(Left)
右(Right)
对于这些移动,规则是要求单元格之间不能沿对角线方向移动. 另外, 从一个单元格移动到下一个单元格时, 一次只能移动一个单元格
要使用状态设计模式来建立一个九宫格移动示例,
建立接口
IMatrix.php
<?php interface IMatrix { public function goUp(); public function goDown(); public function goLeft(); public function goRight(); }
虽然这个状态设计模式有9个状态, 分别对应九个单元格, 但一个状态最多只需要4个变迁
上下文
对于状态中的4个变迁或移动方法, 上下文必须提供相应方法来调用这些变迁方法, 另外还要完成各个状态的实例化.
Context.php
<?php class Context { private $cell1; private $cell2; private $cell3; private $cell4; private $cell5; private $cell6; private $cell7; private $cell8; private $cell9; private $currentState; public function construct() { $this->cell1 = new Cell1State($this); $this->cell2 = new Cell2State($this); $this->cell3 = new Cell3State($this); $this->cell4 = new Cell4State($this); $this->cell5 = new Cell5State($this); $this->cell6 = new Cell6State($this); $this->cell7 = new Cell7State($this); $this->cell8 = new Cell8State($this); $this->cell9 = new Cell9State($this); $this->currentState = $this->cell5; } //调用方法 public function doUp() { $this->currentState->goUp(); } public function doDown() { $this->currentState->goDown(); } public function doLeft() { $this->currentState->goLeft(); } public function doRight() { $this->currentState->goRight(); } //设置当前状态 public function setState(IMatrix $state) { $this->currentState = $state; } //获取状态 public function getCell1State() { return $this->cell1; } public function getCell2State() { return $this->cell2; } public function getCell3State() { return $this->cell3; } public function getCell4State() { return $this->cell4; } public function getCell5State() { return $this->cell5; } public function getCell6State() { return $this->cell6; } public function getCell7State() { return $this->cell7; } public function getCell8State() { return $this->cell8; } public function getCell9State() { return $this->cell9; } }
状态
9个状态表示九宫格中的不同单元格, 为了唯一显示单元格,会分别输出相应到达的单元格数字, 这样能够更清楚地看出穿过矩阵的路线.
Cell1State
<?php class Cell1State implements IMatrix { private $context; public function construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '不合法的移动!<br />'; } public function goRight() { echo '走到<strong>2</strong><br />'; $this->context->setState($this->context->getCell2State()); } public function goUp() { echo '不合法的移动!<br />'; } public function goDown() { echo '走到<strong>4</strong><br />'; $this->context->setState($this->context->getCell4State()); } }
Cell2State
<?php class Cell2State implements IMatrix { private $context; public function construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>1</strong><br />'; $this->context->setState($this->context->getCell1State()); } public function goRight() { echo '走到<strong>3</strong><br />'; $this->context->setState($this->context->getCell3State()); } public function goUp() { echo '不合法的移动!<br />'; } public function goDown() { echo '走到<strong>5</strong><br />'; $this->context->setState($this->context->getCell5State()); } }
Cell3State
<?php class Cell3State implements IMatrix { private $context; public function construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>2</strong><br />'; $this->context->setState($this->context->getCell2State()); } public function goRight() { echo '不合法的移动!<br />'; } public function goUp() { echo '不合法的移动!<br />'; } public function goDown() { echo '走到<strong>6</strong><br />'; $this->context->setState($this->context->getCell6State()); } }
Cell4State
<?php class Cell4State implements IMatrix { private $context; public function construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '不合法的移动!<br />'; } public function goRight() { echo '走到<strong>5</strong><br />'; $this->context->setState($this->context->getCell5State()); } public function goUp() { echo '走到<strong>1</strong><br />'; $this->context->setState($this->context->getCell1State()); } public function goDown() { echo '走到<strong>7</strong><br />'; $this->context->setState($this->context->getCell7State()); } }
Cell5State
<?php class Cell5State implements IMatrix { private $context; public function construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>4</strong><br />'; $this->context->setState($this->context->getCell4State()); } public function goRight() { echo '走到<strong>6</strong><br />'; $this->context->setState($this->context->getCell6State()); } public function goUp() { echo '走到<strong>2</strong><br />'; $this->context->setState($this->context->getCell2State()); } public function goDown() { echo '走到<strong>8</strong><br />'; $this->context->setState($this->context->getCell8State()); } }
Cell6State
<?php class Cell6State implements IMatrix { private $context; public function construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>5</strong><br />'; $this->context->setState($this->context->getCell5State()); } public function goRight() { echo '不合法的移动!<br />'; } public function goUp() { echo '走到<strong>3</strong><br />'; $this->context->setState($this->context->getCell3State()); } public function goDown() { echo '走到<strong>9</strong><br />'; $this->context->setState($this->context->getCell9State()); } }
Cell7State
<?php class Cell7State implements IMatrix { private $context; public function construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '不合法的移动!<br />'; } public function goRight() { echo '走到<strong>8</strong><br />'; $this->context->setState($this->context->getCell8State()); } public function goUp() { echo '走到<strong>4</strong><br />'; $this->context->setState($this->context->getCell4State()); } public function goDown() { echo '不合法的移动!<br />'; } }
Cell8State
<?php class Cell8State implements IMatrix { private $context; public function construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>7</strong><br />'; $this->context->setState($this->context->getCell7State()); } public function goRight() { echo '走到<strong>9</strong><br />'; $this->context->setState($this->context->getCell9State()); } public function goUp() { echo '走到<strong>5</strong><br />'; $this->context->setState($this->context->getCell5State()); } public function goDown() { echo '不合法的移动!<br />'; } }
Cell9State
<?php class Cell9State implements IMatrix { private $context; public function construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>8</strong><br />'; $this->context->setState($this->context->getCell8State()); } public function goRight() { echo '不合法的移动!<br />'; } public function goUp() { echo '走到<strong>6</strong><br />'; $this->context->setState($this->context->getCell6State()); } public function goDown() { echo '不合法的移动!<br />'; } }
要想有效地使用状态设计模式, 真正的难点在于要想象现实或模拟世界是怎么样
客户Client
下面从单元格5开始进行一个上,右,下, 下,左,上的移动
Client.php
<?php function autoload($class_name) { include_once $class_name.'.php'; } class Client { private $context; public function construct() { $this->context = new Context(); $this->context->doUp(); $this->context->doRight(); $this->context->doDown(); $this->context->doDown(); $this->context->doLeft(); $this->context->doUp(); } } $worker = new Client();
运行结果如下
走到2
走到3
走到6
走到9
走到8
走到5
状态模式与PHP
很多人把状态设计模式看做是实现模拟器和游戏的主要方法.总的说来, 这确实是状态模式的目标,不过险些之外, 状态模型(状态引擎)和状态设计模式在PHP中也有很多应用.用PHP完成更大的项目时, 包括Facebook和WordPress, 会有更多的新增特性和当前状态需求.对于这种不断有改变和增长的情况, 就可以采用可扩展的状态模式来管理.
PHP开发人员如何创建包含多个状态的程序, 将决定状态模式的使用范围. 所以不仅状态机在游戏和模拟世界中有很多应用, 实际上状态模型还有更多适用的领域.只要PHP程序的用户会用到一组有限的状态, 开发人员就可以使用状态设计模式.
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
オブジェクト指向PHPに基づいてゲストブックを実装する手順の詳細な説明
以上がPHPステートモードの使い方の詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。