dflydev / finite-state-machine
又一种有限状态机实现
dev-master / 0.0.x-dev
2020-04-17 06:12 UTC
Requires
- php: ^7.4|^8.0
Requires (Dev)
- phpunit/phpunit: ^9.1
- psalm/phar: ^3.11
- squizlabs/php_codesniffer: ^3.5
This package is auto-updated.
Last update: 2024-09-19 04:47:48 UTC
README
这个库是另一个有限状态机的实现。
安装
composer require dflydev/finite-state-machine
用法
给定以下领域类的定义
class DomainObject { public string $state; public ?string $spy = null; public function __construct(string $state = 'new') { $this->state = $state; } }
给定以下领域对象 "graphA" 图的状态定义
$domainObjectGraphDefinition = [ 'class' => DomainObject::class, 'graph' => 'graphA', // default is "default" 'property_path' => 'state', // Configures `PropertyObjectProxy` 'metadata' => [ 'title' => 'Graph A', ], 'states' => [ // a state as associative array ['name' => 'new'], // a state as associative array with metadata [ 'name' => 'pending_review', 'metadata' => ['title' => 'Pending Review'], ], // states as string 'awaiting_changes', 'accepted', 'published', 'rejected', ], // list of all possible transitions 'transitions' => [ 'create' => [ 'from' => ['new'], 'to' => 'pending_review', ], 'ask_for_changes' => [ 'from' => ['pending_review', 'accepted'], 'to' => 'awaiting_changes', 'metadata' => ['title' => 'Ask for changes'], ], 'cancel_changes' => [ 'from' => ['awaiting_changes'], 'to' => 'pending_review', ], 'submit_changes' => [ 'from' => ['awaiting_changes'], 'to' => 'pending_review', ], 'approve' => [ 'from' => ['pending_review', 'rejected'], 'to' => 'accepted', ], 'publish' => [ 'from' => ['accepted'], 'to' => 'published', ], ], // list of all callbacks 'callbacks' => [ // will be called when testing a transition 'guard' => [ 'guard_on_approving_from_rejected' => [ // call the callback on a specific transition 'on' => 'approve', 'from' => 'rejected', // will call the method of this class 'do' => function ( object $object, Transition $transition, State $fromState, State $toState ) { $object->spy = 'guard_on_approving_from_rejected'; // If a guard returns false, the transition will not happen return false; }, // arguments for the callback 'args' => ['object'], ], ], // will be called before applying a transition 'before' => [ 'spy-before-approve' => [ 'on' => 'ask_for_changes', 'from' => 'accepted', 'do' => function ( string $when, object $object, Transition $transition, State $fromState, State $toState ) { Assert::equals($fromState->name(), $object->state); $object->spy = $when . ' ask_for_changes from accepted'; }, ] ], // will be called after applying a transition 'after' => [ 'spy-after-approve' => [ 'on' => 'ask_for_changes', 'from' => 'accepted', 'do' => function ( string $when, object $object, Transition $transition, State $fromState, State $toState ) { Assert::equals($toState->name(), $object->state); Assert::equals('before ask_for_changes from accepted', $object->spy); $object->spy = $when . ' ask_for_changes from accepted'; }, ] ], ] ];
use Dflydev\FiniteStateMachine\FiniteStateMachineFactory; use Dflydev\FiniteStateMachine\Graph\GraphResolver; use Dflydev\FiniteStateMachine\Loader\WinzouArrayLoader; use Dflydev\FiniteStateMachine\ObjectProxy\ObjectProxyResolver; use Dflydev\FiniteStateMachine\ObjectProxy\PropertyObjectProxyFactory; $graphResolver = new GraphResolver(); $objectProxyResolver = new ObjectProxyResolver(); // Add an object proxy that can directly read the state property from our objects $objectProxyResolver->add(new PropertyObjectProxyFactory()); // Load a graph definition into our graph resolver (new WinzouArrayLoader($graphResolver))->load($domainObjectGraphDefinition); $finiteStateMachineFactory = new FiniteStateMachineFactory( $this->getGraphResolver(), $this->getObjectProxyResolver() ); $finiteStateMachine = $finiteStateMachineFactory->build($object); // "new" $finiteStateMachine->currentState()->name(); // (bool) false $finiteStateMachine->can('ask_for_changes'); // (bool) true $finiteStateMachine->can('create'); $finiteStateMachine->apply('create'); // "pending_review" $finiteStateMachine->currentState()->name();
图定义和加载器
图是由状态、转换和回调组成的命名集合。一个对象可以定义多个图。
GraphResolver
负责解析给定对象(和可选的图名)的图定义。
可以手动创建 Graph
并将其添加到 GraphResolver
中。可以使用 Loader
根据特定的资源类型将 Graph
加载到 GraphResolver
中。
winzou/state-machine
此库附带 WinzouArrayLoader
,这是一个与 winzou/state-machine 数组图定义松散兼容的 Loader
实现。
自定义
此库附带一个 Loader
合同。实现此接口允许创建自定义图定义。
许可证
MIT,见 LICENSE。