PHP状态机框架

noo*_*omz 19 php state-machine

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

我必须定义许多if-else逻辑子句,我想通过定义来帮助它变得更有趣:

  1. 过渡所需的条件
  2. 转型后的国家

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

$customer->transition('platinum');
Run Code Online (Sandbox Code Playgroud)

我希望这行代码能够隐式检查客户是否可以转换.或明确检查:

$customer->canTransitTo('platinum');
Run Code Online (Sandbox Code Playgroud)

提前谢谢,诺米兹

Gor*_*don 40

我不知道这样的框架(这并不意味着它不存在).但是,尽管不像链接框架那样具有特征,但State模式实现起来相当简单.考虑下面这个天真的实现:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以做到

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

$car = new Car;
$car->startEngine();
$car->moveForward();
Run Code Online (Sandbox Code Playgroud)

为了减少过大的if/else语句,这应该足够了.请注意,在每次转换时返回新的状态实例效率有点低.就像我说的那样,说明这一点是一个天真的实现.