搜尋
首頁後端開發php教程PHP狀態模式使用詳解

PHP狀態模式使用詳解

May 17, 2018 am 11:49 AM
php使用詳解

這次帶給大家PHP狀態模式使用詳解,PHP狀態模式使用的注意事項有哪些,以下就是實戰案例,一起來看一下。

什麼是狀態設計模式

當一個物件的內在狀態改變時允許改變其行為,這個物件看起來像是改變了其類。

狀態模式主要解決的是當控制一個物件狀態的條件式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類別中,可以把複雜的判斷邏輯簡化。

什麼時候使用狀態模式

在物件中頻繁改變非常依賴條件語句。就其本身來說, 條件語句本身沒有什麼問題(如switch語句或帶else子句的語句),不過, 如果選項太多, 以到程序開始出現混亂, 或者增加或改變選項需要花費太多時間,甚至成為一種負擔, 這就出現了問題

對於狀態設計模式, 每個狀態都有自己的具體類, 它們實現一個公共接口. 我們不用查看對象的控制流, 而是從另一個角度來考慮, 即物件的狀態.

狀態機是一個模型, 其重點包括不同的狀態, 一個狀態到另一個狀態的變遷, 以及導致狀態改變的觸發器.

以開燈關燈為例子, 狀態模型的本質分為3點:

①狀態(關燈和開燈)
②變遷(從關燈到開燈,以及從開燈到關燈)
③觸發器(燈開關)

所以狀態模式都需要一個參與者來追蹤物件所處的狀態. 以Light為例, Light需要知道目前狀態是什麼.

範例:開燈關燈

#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實作的兩個實例-----一個對應關, 一個對應開

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

這個實例化過程用到了一種遞迴, 稱為自引用( self-referral)

建構函數參數中的實參寫為$this, 這是Light類別本身的一個引用. 狀態類別希望接收一個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方法, 就只有提示燈已經被關閉了不會有其他動作.

客戶

Client的所有請求都是透過Light發出, Client和任何狀態類別之間都沒有直接連接, 包括IState介面.下面的Client顯示了觸發兩個狀態中所有方法的請求.

Client.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();

增加狀態

對於所有的設計模式來說,很重要的一個面向是: 利用這些設計模式可以很容易地做出修改. 與其他模式一樣,狀態模式也很易於更新和改變. 下面在這個燈的示例上再加兩個狀態:更亮(Brighter)和最亮( Brightest)

現在變成了4個狀態, 序列有所改變. '關'(off)狀態只能變到"開"(on)狀態, on狀態不能變到off狀態.on狀態只能變到"更亮"(brighter)狀態和"最亮"(brightest)狀態. 只能最亮狀態才可能變到關狀態.

##改變介面

要改變的第一個參與者是介面IState, 這個介面中必須指定對應的方法, 可以用來遷移到brighter和brightest狀態.

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.&#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 '不合法的移动!<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.&#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中文网其它相关文章!

推荐阅读:

PHP基於物件導向實作留言本步驟詳解

#PHP依賴倒置案例詳解

以上是PHP狀態模式使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
您如何修改PHP會話中存儲的數據?您如何修改PHP會話中存儲的數據?Apr 27, 2025 am 12:23 AM

tomodifyDataNaphPsession,startTheSessionWithSession_start(),然後使用$ _sessionToset,修改,orremovevariables.1)startThesession.2)setthesession.2)使用$ _session.3)setormodifysessessvariables.3)emovervariableswithunset()

舉一個在PHP會話中存儲數組的示例。舉一個在PHP會話中存儲數組的示例。Apr 27, 2025 am 12:20 AM

在PHP會話中可以存儲數組。 1.啟動會話,使用session_start()。 2.創建數組並存儲在$_SESSION中。 3.通過$_SESSION檢索數組。 4.優化會話數據以提升性能。

垃圾收集如何用於PHP會議?垃圾收集如何用於PHP會議?Apr 27, 2025 am 12:19 AM

PHP會話垃圾回收通過概率機制觸發,清理過期會話數據。 1)配置文件中設置觸發概率和會話生命週期;2)可使用cron任務優化高負載應用;3)需平衡垃圾回收頻率與性能,避免數據丟失。

如何在PHP中跟踪會話活動?如何在PHP中跟踪會話活動?Apr 27, 2025 am 12:10 AM

PHP中追踪用戶會話活動通過會話管理實現。 1)使用session_start()啟動會話。 2)通過$_SESSION數組存儲和訪問數據。 3)調用session_destroy()結束會話。會話追踪用於用戶行為分析、安全監控和性能優化。

如何使用數據庫存儲PHP會話數據?如何使用數據庫存儲PHP會話數據?Apr 27, 2025 am 12:02 AM

利用數據庫存儲PHP會話數據可以提高性能和可擴展性。 1)配置MySQL存儲會話數據:在php.ini或PHP代碼中設置會話處理器。 2)實現自定義會話處理器:定義open、close、read、write等函數與數據庫交互。 3)優化和最佳實踐:使用索引、緩存、數據壓縮和分佈式存儲來提升性能。

簡單地說明PHP會話的概念。簡單地說明PHP會話的概念。Apr 26, 2025 am 12:09 AM

phpsessionstrackuserdataacrossmultiplepagerequestsusingauniqueIdStoredInAcookie.here'showtomanageThemeffectionaly:1)startAsessionWithSessionWwithSession_start()和stordoredAtain $ _session.2)

您如何循環中存儲在PHP會話中的所有值?您如何循環中存儲在PHP會話中的所有值?Apr 26, 2025 am 12:06 AM

在PHP中,遍歷會話數據可以通過以下步驟實現:1.使用session_start()啟動會話。 2.通過foreach循環遍歷$_SESSION數組中的所有鍵值對。 3.處理複雜數據結構時,使用is_array()或is_object()函數,並用print_r()輸出詳細信息。 4.優化遍歷時,可採用分頁處理,避免一次性處理大量數據。這將幫助你在實際項目中更有效地管理和使用PHP會話數據。

說明如何使用會話進行用戶身份驗證。說明如何使用會話進行用戶身份驗證。Apr 26, 2025 am 12:04 AM

會話通過服務器端的狀態管理機制實現用戶認證。 1)會話創建並生成唯一ID,2)ID通過cookies傳遞,3)服務器存儲並通過ID訪問會話數據,4)實現用戶認證和狀態管理,提升應用安全性和用戶體驗。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具