Home >Backend Development >PHP Tutorial >Detailed explanation of using PHP state mode
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.'.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();
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.'.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中文网其它相关文章!
推荐阅读:
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!