写点什么

行为型设计模式 - 状态 State

作者:菜皮日记
  • 2023-09-08
    北京
  • 本文字数:1503 字

    阅读完需:约 5 分钟

简介

跟状态机密切相关。有限状态机 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.
复制代码


用户头像

菜皮日记

关注

全干程序员 2018-08-08 加入

还未添加个人简介

评论

发布
暂无评论
行为型设计模式-状态 State_设计模式_菜皮日记_InfoQ写作社区