dddphp / state-machine
PHP 状态机
v0.0.1-beta
2023-08-06 05:53 UTC
Requires
- php: ^8.1
- psr/event-dispatcher: ^1.0
Requires (Dev)
- phpunit/phpunit: ^10.2
- vimeo/psalm: ^5.13
This package is not auto-updated.
Last update: 2024-09-22 11:25:18 UTC
README
状态机库旨在提供一个 易于使用、轻量级、灵活 和 可扩展,以及 类型安全 的 PHP 状态机实现,适用于企业级应用。
安装(通过 composer)
{ "require": { "dddphp/state-machine": "*" } }
用户指南
开始使用
-
状态机构建器
- 状态机构建器用于生成状态机定义。可以通过 StateMachineBuilderFactory 创建 StateMachineBuilder。
- StateMachineBuilder 由 TransitionBuilder(InternalTransitionBuilder / ExternalTransitionBuilder)组成,用于构建状态之间的转换。
- 内部状态在创建转换或状态动作时隐式构建。
- 由同一状态机构建器创建的所有状态机实例共享相同的定义数据,以优化内存使用。
- 状态机构建器以延迟方式生成状态机定义。当构建器创建第一个状态机实例时,将生成状态机定义,这需要消耗时间。但一旦状态机定义生成后,后续状态机实例的创建将更快。通常,应尽可能重复使用状态机构建器。
为了创建状态机,用户需要首先创建状态机构建器。例如
$builder = StateMachineBuilderFactory::create();
-
流畅 API 在创建状态机构建器后,我们可以使用流畅 API 定义状态机的状态/转换/动作。
$builder->externalTransition() ->from(self::STATEA) ->to(self::STATEB) ->on(self::EVENTGoToB) ->when($this->checkCondition()) ->perform($this->doAction());
在状态 'A' 到状态 'B' 之间构建一个 外部转换,并由接收到的事件 'GoToB' 触发。
$builder->internalTransition() ->within(self::STATEA) ->on(self::INTERNAL_EVENT) ->when($this->checkCondition()) ->perform($this->doAction());
在状态 'A' 内部构建一个设置为高优先级的 内部转换,在事件 'INTERNAL_EVENT' 上执行 '$this->doAction()'。内部转换意味着转换完成后,没有状态退出或进入。转换优先级用于在状态机扩展时覆盖原始转换。
$builder->externalTransition() ->from(self::STATEC) ->to(self::STATED) ->on(self::EVENTGoToD) ->when( new class () implements ConditionInterface { public function isSatisfied($context): bool { echo "Check condition : " . $context . "\n"; return true; } public function name(): string { return ''; } }) ->perform( new class () implements ActionInterface { public function execute($from, $to, $event, $context): void { echo $context . " from:" . $from . " to:" . $to . " on:" . $event; } }; );
在满足条件限制的外部上下文中,从状态 'C' 到状态 'D' 构建 条件转换,然后在事件 'GoToD' 上调用动作方法。
-
创建新的状态机实例
在用户定义了状态机行为之后,用户可以通过构建器创建一个新的状态机实例。注意,一旦从构建器创建了状态机实例,构建器就不再可以用来定义状态机的任何新元素。
从状态机构建器创建新的状态机。
$stateMachine = $builder->build(self::MACHINE_ID);
-
触发转换
在创建状态机之后,用户可以触发事件,并带有上下文来在状态机内部触发转换。例如。
$target = $stateMachine->fire(self::STATE1, self::EVENT1, $this->context);