search
HomeBackend DevelopmentPHP TutorialDetailed explanation of using PHP state mode
Detailed explanation of using PHP state modeMay 17, 2018 am 11:49 AM
phpuseDetailed explanation

This time I will bring you a detailed explanation of the use of PHP status mode. What are the precautions for using PHP status mode? The following is a practical case, let's take a look.

What is the state design pattern

Allows the behavior of an object to change when its internal state changes. The object appears to have changed. its kind.

The state mode mainly solves the situation when the conditional expression that controls the state of an object is too complex. By transferring the state judgment logic to a series of classes representing different states, complex judgment logic can be simplified.

When to use the state pattern

Frequent changes in objects rely heavily on conditional statements. On its own, there is nothing wrong with conditional statements (such as switch statements or statements with else clauses). However, if there are too many options, the program begins to get confused, or adding or changing options takes too much time. It even becomes a burden, which creates a problem

For the state design pattern, each state has its own concrete class, which implements a public interface. We don't have to look at the control flow of the object, but from another Consider it from one perspective, that is, the state of the object.

A state machine is a model, which focuses on different states, the transition from one state to another, and the triggers that cause state changes.

Taking turning the lights on and off as an example, the essence of the state model is divided into three points:

① State (turning off the lights and turning on the lights)
② Transition (from turning off the lights to turning on the lights, And from turning on the light to turning off the light)
③Trigger (light switch)

So the state mode requires a participant to track the state of the object. Taking Light as an example, Light needs Know what the current status is.

Example: Turn the light on and off

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;
  }
}

at In the constructor , Light instantiates two instances of IState implementation ----- one corresponding to off, one corresponding to on.

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

This instantiation process uses a kind of recursion, called self-reference ( self-referral)

ConstructionThe actual parameters in function parameters are written as $this, which is a reference to the Light class itself. The state class hopes to receive a Light class instance as a parameter,.

The setState method requires a state object as an actual parameter to set a current state. Once a state is triggered, this state will send information to the Light class, specifying the current state.

State Example

IState interface

IState.php

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

The implementation class of this interface

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>";
  }
}

The default state is OffState, which must implement the IState methods turnLightOn and turnLightOff. When Light calls the turnLightOn method, it will display (light Open! You can see the handsome guy chenqionghe), and then set OnState to the current state. However, if the turnLightOff method of OffState is called, only the reminder light has been turned off and no other actions will occur.

All requests from Client

Client are made through Light. There is no direct connection between Client and any state class, including the IState interface. The following Client shows the requests that trigger all methods in the two states. .

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

Add status

This is a very important aspect for all design patterns Yes: These design patterns make it easy to make changes. Like other patterns, state patterns are easy to update and change. Let’s add two more states to the light example: Brighter and Brightest Brightest)

Now it has become 4 states, and the sequence has changed. The 'off' (off) state can only be changed to the "on" (on) state, and the on state cannot be changed to the off state. The on state It can only be changed to the "brighter" state and the "brightest" state. Only the brightest state can be changed to the off state.

Change interface

The first participant to be changed is the interface IState. The corresponding method must be specified in this interface, which can be used to migrate to the brighter and brightest states.

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中文网其它相关文章!

推荐阅读:

Detailed explanation of the steps to implement guestbook based on object-oriented PHP

Detailed explanation of PHP dependency inversion case

The above is the detailed content of Detailed explanation of using PHP state mode. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么设置implode没有分隔符php怎么设置implode没有分隔符Apr 18, 2022 pm 05:39 PM

在PHP中,可以利用implode()函数的第一个参数来设置没有分隔符,该函数的第一个参数用于规定数组元素之间放置的内容,默认是空字符串,也可将第一个参数设置为空,语法为“implode(数组)”或者“implode("",数组)”。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool