PHP design pattern state pattern definition and usage

不言
Release: 2023-03-23 12:18:01
Original
1331 people have browsed it

This article mainly introduces the definition and usage of the state pattern of the PHP design pattern. Friends in need can refer to it

The examples in this article describe the definition and usage of the state pattern of the PHP design pattern. Share it with everyone for your reference, the details are as follows:

What is the state design pattern

Allows changes to the internal state of an object when its internal state changes Behavior, the object looks like it has changed its class.

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;
  }
}
Copy after login

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

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

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

The actual parameters in the constructor parameters are written as $this, which is a reference to the Light class itself. Status The class hopes to receive a Light class instance as a parameter. The setState method requires a state object as an actual parameter in order to set a current state. Once a state is triggered, this state will send information to the Light class, specifying the current state. State.

State instance

IState interface

IState.php

##

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

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());
  }
}
Copy after login

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 />";
  }
}
Copy after login

The default state is OffState, which must implement the IState methods turnLightOn and turnLightOff. When Light calls the turnLightOn method, it will display (light on! 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.

Customer

All requests of Client are made through Light. There is no direct connection between Client and any state class, including the IState interface. The Client below 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();
Copy after login

Add status

For all An important aspect of design patterns is that 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 now become 4 states, and the sequence has changed. The 'off' state can only be changed to the 'on' state. The on state cannot be changed to the off state. The on state can only be changed to the "brighter" state and the "brightest" state. Only the brightest state can be changed to the off state.

Change the 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();
}
Copy after login

Now all state classes must contain these four methods, and they all need to be combined into the Light class.

Changing States

When changes are made to the State design pattern, these new changes will have an impact on other aspects of the overall pattern. However, adding changes is fairly simple. , each state has only one specific transition.

Four states

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 />";
  }
}
Copy after login

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 />";
  }
}
Copy after login

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());
  }
}
Copy after login

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 />";
  }
}
Copy after login

##Update Light class

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;
  }
}
Copy after login

更新客户

<?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();
Copy after login

运行结果如下

灯打开!可以看见帅哥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();
}
Copy after login

虽然这个状态设计模式有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;
  }
}
Copy after login

状态

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());
  }
}
Copy after login

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());
  }
}
Copy after login

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());
  }
}
Copy after login

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());
  }
}
Copy after login

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());
  }
}
Copy after login

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());
  }
}
Copy after login

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;;
  }
}
Copy after login

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;;
  }
}
Copy after login

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;;
  }
}
Copy after login

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

客户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();
Copy after login

运行结果如下

走到2
走到3
走到6
走到9
走到8
走到5

状态模式与PHP

很多人把状态设计模式看做是实现模拟器和游戏的主要方法.总的说来, 这确实是状态模式的目标,不过险些之外, 状态模型(状态引擎)和状态设计模式在PHP中也有很多应用.用PHP完成更大的项目时, 包括Facebook和WordPress, 会有更多的新增特性和当前状态需求.对于这种不断有改变和增长的情况, 就可以采用可扩展的状态模式来管理.

PHP开发人员如何创建包含多个状态的程序, 将决定状态模式的使用范围. 所以不仅状态机在游戏和模拟世界中有很多应用, 实际上状态模型还有更多适用的领域.只要PHP程序的用户会用到一组有限的状态, 开发人员就可以使用状态设计模式.

相关推荐:

php设计模式一之命名空间、自动加载类、PSR-0编码规范

16个PHP设计模式介绍


The above is the detailed content of PHP design pattern state pattern definition and usage. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template