乐趣区

关于后端:行为型设计模式状态-State

简介

跟状态机密切相关。无限状态机 FSM 蕴含 状态、事件、动作三个元素。

当产生一个事件时,引发老状态变成新状态,并执行一个动作。

状态和行为间个别是有限度的,如某些行为只能再某些状态下进行,某些状态只能触发某些行为。

简略的状态间转换可应用 if else。

更有条理的能够用查表法:二维表中纵向是状态,横向是事件,value 则是新状态和动作。做成二维数组配置,事件产生时联合以后状态,组成老状态索引去查二维表,得出 value 是新状态和动作,如果没有 value 则不变换

再简单一些之后,可应用状态模式。

角色

  • Context 上下文

    可视为状态机,其外部持有 State 援用

    可通过扭转 State 的值,来达到扭转 Context 行为的目标

  • 形象 State
  • 具体 State

类图

如图,Context/Machine 中能够 changeState 来扭转以后的状态,其中 doThis 和 doThat 签名与 State 统一,这样看起来就像扭转状态的同时,扭转了 Context 的行为。

代码

class Context
{
    private $state;

    public function __construct(State $state)
    {$this->transitionTo($state);
    }

    public function transitionTo(State $state): void
    {echo "Context: Transition to" . get_class($state) . ".\n";
        $this->state = $state;
        $this->state->setContext($this);
    }

    public function request1(): void
    {$this->state->handle1();
    }

    public function request2(): void
    {$this->state->handle2();
    }
}
abstract class State
{
    protected $context;

    public function setContext(Context $context)
    {$this->context = $context;}

    abstract public function handle1(): void;

    abstract public function handle2(): void;}

class ConcreteStateA extends State
{public function handle1(): void
    {
        echo "ConcreteStateA handles request1.\n";
        echo "ConcreteStateA wants to change the state of the context.\n";
        $this->context->transitionTo(new ConcreteStateB());
    }

    public function handle2(): void
    {echo "ConcreteStateA handles request2.\n";}
}

class ConcreteStateB extends State
{public function handle1(): void
    {echo "ConcreteStateB handles request1.\n";}

    public function handle2(): void
    {
        echo "ConcreteStateB handles request2.\n";
        echo "ConcreteStateB wants to change the state of the context.\n";
        $this->context->transitionTo(new ConcreteStateA());
    }
}

$context = new Context(new ConcreteStateA());
$context->request1();
$context->request2();

output:

Context: Transition to ConcreteStateA.
ConcreteStateA handles request1.
ConcreteStateA wants to change the state of the context.
Context: Transition to ConcreteStateB.
ConcreteStateB handles request2.
ConcreteStateB wants to change the state of the context.
Context: Transition to ConcreteStateA.

本文由 mdnice 多平台公布

退出移动版