PHP 状态机框架

2022-08-30 20:18:00

我怀疑是否有任何状态机框架像PHP https://github.com/pluginaweek/state_machine

我不得不定义许多 if-else 逻辑子句,我希望通过定义以下内容来帮助使其更有趣:

  1. 转换所需的条件
  2. 转换后的状态

然后可以重复使用它来检查条件是否匹配,例如

$customer->transition('platinum');

我希望这行代码能够隐式检查客户是否可以转换。或通过以下方式显式检查:

$customer->canTransitTo('platinum');

提前致谢, noomz


答案 1

我不知道这样的框架(这并不意味着它不存在)。但是,虽然不像链接框架那样具有丰富的功能,但状态模式的实现相当简单。考虑下面这个幼稚的实现:

interface EngineState
{
    public function startEngine();
    public function moveForward();
}

class EngineTurnedOffState implements EngineState
{
    public function startEngine()
    {
        echo "Started Engine\n";
        return new EngineTurnedOnState;
    }
    public function moveForward()
    {
        throw new LogicException('Have to start engine first');
    }
}

class EngineTurnedOnState implements EngineState
{
    public function startEngine()
    {
        throw new LogicException('Engine already started');
    }
    public function moveForward()
    {
        echo "Moved Car forward";
        return $this;
    }
}

定义状态后,只需将它们应用于主对象:

class Car implements EngineState
{
    protected $state;
    public function __construct()
    {
        $this->state = new EngineTurnedOffState;
    }
    public function startEngine()
    {
        $this->state = $this->state->startEngine();
    }
    public function moveForward()
    {
        $this->state = $this->state->moveForward();
    }
}

然后你可以做

$car = new Car;
try {
    $car->moveForward(); // throws Exception
} catch(LogicException $e) {
    echo $e->getMessage();
}

$car = new Car;
$car->startEngine();
$car->moveForward();

对于减少过大的 if/else 语句,这应该足够了。请注意,在每次转换时返回新的状态实例有些低效。就像我说的,这是一个幼稚的实现来说明这一点。


答案 2

推荐