Workflow组件

Workflow组件提供的工具用来管理一个工作流或有限状态机(finite state machine)。

3.2全新 Workflow组件在Symfony 3.2中被全新引入。

安装 

你可以通过下述两种方式安装:

然后,包容 vendor/autoload.php 文件,以开启Composer提供的自动加载机制。否则,你的程序将无法找到这个Symfony组件的类。

创建一个工作流 

工作流组件提供了一个面向对象的方式,来定义你的对象所经历的进程或生命周期。进程中的每一步,或每一个阶段,被称之为一个 place(位置)。你还必须定义 transitions(过渡)来描述从一个位置到另一个位置时的action(动作)。

一组位置及其过渡,创建了一个 definition(定义)。一个工作流,需要的是一个 Definition 以及把状态(state)写入对象实例 (如,一个 MarkingStoreInterface 实例) 的方式。

思考以下博客主题的例程。每篇主题可以有一个预定义状态(predefined status,比如草稿、审稿、拒发、已发)的编号。在一个workflow中,这些状态被称为 places。你可以像这样定义这个工作流:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\Transition;
use Symfony\Component\Workflow\Workflow;
use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore;
 
$builder = new DefinitionBuilder();
$builder->addPlaces(['draft', 'review', 'rejected', 'published']);
 
// Transitions are defined with a unique name, an origin place and a destination place
// 过渡是用一个唯一名称、一个原始位置、一个目标位置来定义的
$builder->addTransition(new Transition('to_review', 'draft', 'review'));
$builder->addTransition(new Transition('publish', 'review', 'published'));
$builder->addTransition(new Transition('reject', 'review', 'rejected'));
 
$definition = $builder->build();
 
$marking = new SingleStateMarkingStore('currentState');
$workflow = new Workflow($definition, $marking);

Workflow 现在可以帮你决定,根据主题所处的place(位置),能够对它做何种操作。这可以将你的domain logic(域对象逻辑)保持在同一个地方,而不是散布到程序中。

当你定义了多个工作流,应当考虑使用 Registry(登记),它是一个可以对不同工作流进行存储和提供访问的对象。一个Registry将帮你决定某个工作流“是否支持你正在尝试使用它”的对象:

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\Workflow\Registry;
use Acme\Entity\BlogPost;
use Acme\Entity\Newsletter;
 
$blogWorkflow = ...
$newsletterWorkflow = ...
 
$registry = new Registry();
$registry->add($blogWorkflow, BlogPost::class);
$registry->add($newsletterWorkflow, Newsletter::class);

用法 

当你配置好工作流的 Registry 时,可以像下面这样使用它:

1
2
3
4
5
6
7
8
9
10
// ...
$post = new BlogPost();
$workflow = $registry->get($post);
 
$workflow->can($post, 'publish'); // False
$workflow->can($post, 'to_review'); // True
 
$workflow->apply($post, 'to_review');
$workflow->can($post, 'publish'); // True
$workflow->getEnabledTransitions($post); // ['publish', 'reject']

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)