masterfri / stateful
Laravel 5 的有限状态机实现
v1.1
2017-07-26 13:36 UTC
Requires
- php: >=5.6.0
- laravel/framework: ~5.3
Requires (Dev)
- phpunit/phpunit: ~5.4
This package is not auto-updated.
Last update: 2024-09-21 14:32:58 UTC
README
Stateful 是 Laravel 5 有限状态机的另一种实现。它允许以最小的努力将任何类转换为状态实体。这种特定实现的基本概念是,实体的状态变化是由信号触发的,这些信号可以手动发送给实体,也可以映射到事件。
安装
Stateful 可以通过 composer 安装
composer require masterfri/stateful
如果您想将信号映射到事件,您需要在 config/app.php
中注册服务提供者,如下所示
'providers' => [
...
Masterfri\Stateful\Providers\StatefulServiceProvider::class,
]
然后您需要创建 config/stateful.php
,内容如下
return [
'event_mapping' => [
'eloquent.saving: *' => 'save',
...
],
];
您可以根据需要定义事件和信号之间的关系。不同的事件可以绑定到同一信号,同样,一个事件也可以触发多个信号。
定义状态实体
Stateful 必须实现接口 Masterfri\Stateful\Contracts\Stateful
。Trait Masterfri\Stateful\Traits\StatefulTrait
包含控制实体所需的所有方法,您只需在定义状态机时实现方法 createStateMachine()
。
public function createStateMachine()
{
return FSM::build([
'states' => [ // list of states
'state1', // state can be defined without options
'state2' => [ // or with options
'initial' => true, // optional, defines that state is initial, there must be exactly one initial state
'enter' => function($entity) {}, // optional, this function is executed when entity enters the state
'leave' => function($entity) {}, // optional, this function is executed when entity leaves the state
'finite' => true, // optional, defines that state is finite, there may be any amount of finite states
],
],
'transitions' => [ // list of transitions
[
'source', // source state name
'destination', // destination state name
'signal', // type of signal that can trigger this transition
'condition' => function($entity, $signal) {}, // optional, this finction is an additional condition that defines if transition has to be triggered
'transit' => function($entity) {}, // optional, this function is executed when entity goes through the transition
]
],
]);
}
以下是一个简单的示例
use Masterfri\Stateful\Contracts\Stateful;
use Masterfri\Stateful\Traits\StatefulTrait;
use Masterfri\Stateful\FSM;
class Order extends Model implements Stateful
{
use StatefulTrait;
...
public function createStateMachine()
{
return FSM::build([
'states' => [
'new' => ['initial' => true],
'placed' => [
'enter' => function($model) {
$model->sendCustomerEmail('Your order has been placed', 'placed.tmpl');
},
],
'processed',
'shipped' => [
'enter' => function($model) {
$model->sendCustomerEmail('Your order has been shipped', 'shipped.tmpl');
},
],
'completed' => ['finite' => true],
],
'transitions' => [
// Order is submitted by customer
['new', 'placed', 'submit'],
// Manager processed the order
['placed', 'processed', 'process',
'condition' => function($model) {
return $model->canBeProcessed();
}
],
// Manager reviewed order and marked it as non-processable
['placed', 'completed', 'process',
'condition' => function($model) {
return !$model->canBeProcessed();
},
'transit' => function($model) {
$model->sendCustomerEmail('Sorry your order can not be processed', 'rejected.tmpl');
$model->markAsRejected();
}
],
// Manager received information from delivery service and filled out delivery information on the order
['processed', 'shipped', 'ship'],
// Manager received feedback from customer
['shipped', 'completed', 'close']
]);
}