ホームページ  >  記事  >  バックエンド開発  >  PHP 設計パターン状態パターンの定義と使用法

PHP 設計パターン状態パターンの定義と使用法

不言
不言オリジナル
2018-04-09 16:43:231285ブラウズ

この記事では、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;
  }
}

コンストラクターで、Light は IState 実装の 2 つのインスタンスをインスタンス化します。1 つはオフに対応し、もう 1 つはオンに対応します

$this->offState = new OffState($this);
$this->onState = new OnState($this);

このインスタンス化プロセスでは、自己参照 (self-referral) と呼ばれる一種の再帰です

コンストラクター パラメーター内の実際のパラメーターは、Light クラス自体への参照である $this として記述されます。状態クラスは、Light クラスのインスタンスを次のように受け取ります。

setState メソッドは、現在の状態を設定するために使用されます。状態がトリガーされると、この状態は現在の状態を指定して Light クラスに情報を送信します。インスタンス

IStateインターフェース

IState.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 />";
  }
}

デフォルトの状態はOffStateです。IStateメソッドturnLightOnとturnLightOffを実装する必要があります。LightはturnLightOnメソッドを呼び出します。表示されます(ライトが点灯しています!ハンサムな男性のchenqiongheが見えます)。その後、OnStateを現在の状態に設定しますただし、OffState のturnLightOff メソッドが呼び出された場合は、ライトがオフになったことを示すだけであり、他のアクションはありません。クライアントと、IState インターフェイスを含む状態クラスの間に直接接続はありません。以下のクライアントは、2 つの状態のすべてのメソッドをトリガーするリクエストを示しています。

すべてのデザイン パターンの重要な点は、これらのデザイン パターンを使用して簡単に変更できることです。他のパターンと同様に、状態パターンも簡単に更新および変更できます。次に、このライトの例にさらに 2 つの状態を追加します: Brighter と Brightest

これで 4 つの状態になり、シーケンスが変更されました。 「オフ」状態は「オン」状態にのみ変更でき、オン状態は「オフ」状態にのみ変更できます。 「より明るい」状態と「最も明るい」状態のみを変更できます。オフ状態に変更することができます。

最初に変更する参加者はインターフェイス IState です。これは、より明るい状態と最も明るい状態に移行するために使用できます。

IState.php

<?php
function __autoload($class_name)
{
  include_once $class_name.&#39;.php&#39;;
}
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();

今度は、すべての状態クラスにこれらの 4 つのメソッドが含まれている必要があり、それらをすべて組み合わせる必要があります。

状態を変更します

状態の設計パターンに変更がある場合、これらの新しい変更はパターン全体の他の側面に影響を与えます。ただし、変更の追加は非常に簡単で、各状態には影響があります。特定の遷移が 1 つだけ

OnState.php

<?php
interface IState
{
  public function turnLightOn();
  public function turnLightOff();
  public function turnBrighter();
  public function turnBrightest();
}

Light クラスを更新

Light.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 />";
  }
}

更新客户

<?php
function __autoload($class_name)
{
  include_once $class_name.&#39;.php&#39;;
}
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 &#39;不合法的移动!<br />&#39;;
  }
  public function goRight()
  {
    echo &#39;走到<strong>2</strong><br />&#39;;
    $this->context->setState($this->context->getCell2State());
  }
  public function goUp()
  {
    echo &#39;不合法的移动!<br />&#39;;
  }
  public function goDown()
  {
    echo &#39;走到<strong>4</strong><br />&#39;;
    $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 &#39;走到<strong>1</strong><br />&#39;;
    $this->context->setState($this->context->getCell1State());
  }
  public function goRight()
  {
    echo &#39;走到<strong>3</strong><br />&#39;;
    $this->context->setState($this->context->getCell3State());
  }
  public function goUp()
  {
    echo &#39;不合法的移动!<br />&#39;;
  }
  public function goDown()
  {
    echo &#39;走到<strong>5</strong><br />&#39;;
    $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 &#39;走到<strong>2</strong><br />&#39;;
    $this->context->setState($this->context->getCell2State());
  }
  public function goRight()
  {
    echo &#39;不合法的移动!<br />&#39;;
  }
  public function goUp()
  {
    echo &#39;不合法的移动!<br />&#39;;
  }
  public function goDown()
  {
    echo &#39;走到<strong>6</strong><br />&#39;;
    $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 &#39;不合法的移动!<br />&#39;;
  }
  public function goRight()
  {
    echo &#39;走到<strong>5</strong><br />&#39;;
    $this->context->setState($this->context->getCell5State());
  }
  public function goUp()
  {
    echo &#39;走到<strong>1</strong><br />&#39;;
    $this->context->setState($this->context->getCell1State());
  }
  public function goDown()
  {
    echo &#39;走到<strong>7</strong><br />&#39;;
    $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 &#39;走到<strong>4</strong><br />&#39;;
    $this->context->setState($this->context->getCell4State());
  }
  public function goRight()
  {
    echo &#39;走到<strong>6</strong><br />&#39;;
    $this->context->setState($this->context->getCell6State());
  }
  public function goUp()
  {
    echo &#39;走到<strong>2</strong><br />&#39;;
    $this->context->setState($this->context->getCell2State());
  }
  public function goDown()
  {
    echo &#39;走到<strong>8</strong><br />&#39;;
    $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 &#39;走到<strong>5</strong><br />&#39;;
    $this->context->setState($this->context->getCell5State());
  }
  public function goRight()
  {
    echo &#39;不合法的移动!<br />&#39;;
  }
  public function goUp()
  {
    echo &#39;走到<strong>3</strong><br />&#39;;
    $this->context->setState($this->context->getCell3State());
  }
  public function goDown()
  {
    echo &#39;走到<strong>9</strong><br />&#39;;
    $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 &#39;不合法的移动!<br />&#39;;
  }
  public function goRight()
  {
    echo &#39;走到<strong>8</strong><br />&#39;;
    $this->context->setState($this->context->getCell8State());
  }
  public function goUp()
  {
    echo &#39;走到<strong>4</strong><br />&#39;;
    $this->context->setState($this->context->getCell4State());
  }
  public function goDown()
  {
    echo &#39;不合法的移动!<br />&#39;;
  }
}

Cell8State

<?php
class Cell8State implements IMatrix
{
  private $context;
  public function __construct(Context $contextNow)
  {
    $this->context = $contextNow;
  }
  public function goLeft()
  {
    echo &#39;走到<strong>7</strong><br />&#39;;
    $this->context->setState($this->context->getCell7State());
  }
  public function goRight()
  {
    echo &#39;走到<strong>9</strong><br />&#39;;
    $this->context->setState($this->context->getCell9State());
  }
  public function goUp()
  {
    echo &#39;走到<strong>5</strong><br />&#39;;
    $this->context->setState($this->context->getCell5State());
  }
  public function goDown()
  {
    echo &#39;不合法的移动!<br />&#39;;
  }
}

Cell9State

<?php
class Cell9State implements IMatrix
{
  private $context;
  public function __construct(Context $contextNow)
  {
    $this->context = $contextNow;
  }
  public function goLeft()
  {
    echo &#39;走到<strong>8</strong><br />&#39;;
    $this->context->setState($this->context->getCell8State());
  }
  public function goRight()
  {
    echo &#39;不合法的移动!<br />&#39;;
  }
  public function goUp()
  {
    echo &#39;走到<strong>6</strong><br />&#39;;
    $this->context->setState($this->context->getCell6State());
  }
  public function goDown()
  {
    echo &#39;不合法的移动!<br />&#39;;
  }
}

要想有效地使用状态设计模式, 真正的难点在于要想象现实或模拟世界是怎么样

客户Client

下面从单元格5开始进行一个上,右,下, 下,左,上的移动

Client.php

<?php
function __autoload($class_name)
{
  include_once $class_name.&#39;.php&#39;;
}
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设计模式一之命名空间、自动加载类、PSR-0编码规范

16个PHP设计模式介绍


以上がPHP 設計パターン状態パターンの定義と使用法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。