我怀疑有没有像https://github.com/pluginaweek/state_machine这样的状态机框架。
我不得不定义许多if-else逻辑子句,我希望通过定义以下内容来使其更有趣:
转换后transition
然后,可以重用它来检查条件是否匹配,例如
$customer->transition('platinum');
我希望这一行代码能够隐式地检查客户是否可以转换。或通过以下方式显式检查:
$customer->canTransitTo('platinum');
提前谢谢你,努姆兹
发布于 2010-11-25 16:59:45
我不知道这样的框架(这并不意味着它不存在)。但是,虽然不像链接框架那样具有丰富的功能,但State pattern实现起来相当简单。考虑下面这个简单的实现:
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语句,这应该足够了。请注意,在每次转换时返回一个新的状态实例有点低效。正如我所说的,这是一个天真的实现来说明这一点。
发布于 2010-11-25 17:04:19
发布于 2012-11-19 05:13:05
我一直在开发一个简单的PHP有限状态机库,有点类似于rails的state_machine。代码在这里:https://github.com/chriswoodford/techne/tree/v0.1
一个汽车例子,类似于上面选择的答案,看起来像这样:
初始化
$machine = new StateMachine\FiniteStateMachine();
$machine->addEvent('start', array('parked' => 'idling'));
$machine->addEvent('drive', array('idling' => 'driving'));
$machine->addEvent('stop', array('driving' => 'idling'));
$machine->addEvent('park', array('idling' => 'parked'));
$machine->setInitialState('parked');
用法
$machine->start();
echo $machine->getCurrentStatus();
// prints "idling"
$machine->drive();
echo $machine->getCurrentStatus();
// prints "driving"
$machine->stop();
echo $machine->getCurrentStatus();
// prints "idling"
$machine->park();
echo $machine->getCurrentStatus();
// prints "parked"
它缺少一个显式定义的接口,因为它使用__call()魔术方法来接受消息,但这可以通过adapter轻松解决。
https://stackoverflow.com/questions/4274031
复制相似问题