PHP 디자인 패턴 상태 패턴 정의 및 사용법

不言
풀어 주다: 2023-03-23 12:18:01
원래의
1337명이 탐색했습니다.

이 글은 주로 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 구현의 두 인스턴스를 인스턴스화합니다. 하나는 off에 해당하고 다른 하나는 on

$this->offState = new OffState($this);
$this->onState = new OnState($this);
로그인 후 복사

에 해당합니다. 자기 참조(self-referral)라고 불리는 일종의 재귀

생성자 매개변수의 실제 매개변수는 $this로 작성되는데, 이는 Light 클래스 자체에 대한 참조입니다. 상태 클래스는 Light 클래스 인스턴스를 다음과 같이 받기를 희망합니다.

setState 메소드는 현재 상태를 설정하는 것입니다. 상태 객체는 실제 매개변수로 사용됩니다. 상태가 트리거되면 이 상태는 현재 상태를 지정하는 정보를 보냅니다. 인스턴스

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 메소드가 호출되면 조명이 꺼졌다는 것만 표시되며 다른 작업은 없습니다.

Customer

클라이언트의 모든 요청은 Light를 통해 이루어집니다. IState 인터페이스를 포함하여 클라이언트와 모든 상태 클래스 간에는 직접적인 연결이 없습니다. 아래 클라이언트는 두 상태의 모든 메서드를 트리거하는 요청을 보여줍니다.

모든 디자인 패턴의 중요한 측면은 이러한 디자인 패턴을 사용하여 쉽게 수정할 수 있다는 것입니다. 다른 패턴과 마찬가지로 상태 패턴도 업데이트 및 변경이 쉽습니다. 다음으로 이 조명 예제에 두 가지 상태를 더 추가합니다: 더 밝게 이제 4가지 상태가 되었으며, 순서가 바뀌었습니다. '켜짐' 상태로만 변경 가능하며, 켜짐 상태는 꺼짐 상태로만 변경 가능합니다. "밝은" 상태와 "가장 밝은" 상태만 변경할 수 있습니다. 꺼진 상태로 변경될 수 있습니다.

인터페이스 변경

변경할 첫 번째 참가자는 해당 메서드입니다. 더 밝고 가장 밝은 상태로 마이그레이션하는 데 사용할 수 있습니다.

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가지 메서드가 포함되어야 하며 모두 결합해야 합니다.

상태 변경

상태 디자인 패턴이 변경되면 이러한 새로운 변경 사항은 전체 패턴의 다른 측면에 영향을 미칩니다. 그러나 변경 사항을 추가하는 것은 매우 간단합니다.

4개 상태

OnState.php

<?php
interface IState
{
  public function turnLightOn();
  public function turnLightOff();
  public function turnBrighter();
  public function turnBrightest();
}
로그인 후 복사

라이트 클래스 업데이트

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿