跳到内容

工作流和状态机

编辑此页

工作流

工作流是你应用程序中流程的模型。它可以是博客文章从草稿到审查和发布的流程。另一个例子是用户提交一系列不同的表单来完成任务。这些流程最好与你的模型分离,并在配置中定义。

工作流的**定义**包括位置和从一个位置到另一个位置的动作。这些动作被称为**转换**。工作流还需要知道每个对象在工作流中的位置。**标记存储**将当前位置写入对象的属性。

注意

上面的术语在讨论工作流和 Petri 网 时常用。

示例

最简单的工作流看起来像这样。它包含两个位置和一个转换。

A simple state diagram showing a single transition between two places.

当工作流描述真实的业务案例时,可能会更复杂。下面的工作流描述了填写职位申请的流程。

A complex state diagram showing many places with multiple possible transitions between them.

在这个例子中,当你填写职位申请时,根据你申请的职位,有 4 到 7 个步骤。有些职位需要用户回答性格测试、逻辑测试和/或正式要求。有些职位不需要。GuardEvent 用于决定特定申请允许的后续步骤。

通过像这样定义工作流,可以概览流程的样子。流程逻辑不会与控制器、模型或视图混合在一起。步骤的顺序可以通过仅更改配置来更改。

状态机

状态机是工作流的子集,其目的是保持模型的某个状态。它们之间最重要的区别是

  • 工作流可以同时处于多个位置,而状态机不能;
  • 为了应用转换,工作流要求对象处于转换的所有先前位置,而状态机仅要求对象至少处于这些位置之一。

示例

拉取请求从初始的“start”状态开始,然后进入“test”状态,例如在持续集成堆栈上运行测试。完成此操作后,拉取请求处于“review”状态,贡献者可以在此状态下要求更改、拒绝或接受拉取请求。在任何时候,你也可以“update”拉取请求,这将导致另一次持续集成运行。

A state diagram for the pull request process described previously.

以下是拉取请求状态机的配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# config/packages/workflow.yaml
framework:
    workflows:
        pull_request:
            type: 'state_machine'
            marking_store:
                 type: 'method'
                 property: 'currentPlace'
            # The "supports" option is useful only if you are using Twig functions ('workflow_*')
            supports:
                - App\Entity\PullRequest
            initial_marking: start
            places:
                - start
                - coding
                - test
                - review
                - merged
                - closed
            transitions:
                submit:
                    from: start
                    to: test
                update:
                    from: [coding, test, review]
                    to: test
                wait_for_review:
                    from: test
                    to: review
                request_change:
                    from: review
                    to: coding
                accept:
                    from: review
                    to: merged
                reject:
                    from: review
                    to: closed
                reopen:
                    from: closed
                    to: review

提示

如果你的转换定义了工作流中使用的所有位置,则可以省略 places 选项。Symfony 将自动从转换中提取位置。

7.1

Symfony 7.1 中引入了对省略 places 选项的支持。

Symfony 会自动为你配置中定义的每个工作流 (Workflow) 或状态机 (StateMachine) 创建一个服务。你可以通过使用服务自动装配并在类中使用 camelCased 工作流名称 + Workflow 作为参数名称,在类中使用工作流。如果是状态机类型,请使用 camelCased 工作流名称 + StateMachine

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// ...
use App\Entity\PullRequest;
use Symfony\Component\Workflow\WorkflowInterface;

class SomeService
{
    public function __construct(
        // Symfony will inject the 'pull_request' state machine configured before
        private WorkflowInterface $pullRequestStateMachine,
    ) {
    }

    public function someMethod(PullRequest $pullRequest): void
    {
        $this->pullRequestStateMachine->apply($pullRequest, 'wait_for_review', [
            'log_comment' => 'My logging comment for the wait for review transition.',
        ]);
        // ...
    }

    // ...
}

自动和手动验证

在缓存预热期间,Symfony 会验证配置文件中定义的工作流和状态机。如果你的工作流或状态机是以编程方式而不是在配置文件中定义的,你可以使用 WorkflowValidator 和 StateMachineValidator 来验证它们

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// ...
use Symfony\Component\Workflow\Definition;
use Symfony\Component\Workflow\StateMachine;
use Symfony\Component\Workflow\Validator\StateMachineValidator;

$states = ['created', 'activated', 'deleted'];
$stateTransitions = [
    new Transition('activate', 'created', 'activated'),
    // This duplicate event "from" the "created" state is invalid
    new Transition('activate', 'created', 'deleted'),
    new Transition('delete', 'activated', 'deleted'),
];

// No validation is done upon initialization
$definition = new Definition($states, $stateTransitions);

$validator = new StateMachineValidator();
// Throws InvalidDefinitionException in case of an invalid definition
$validator->validate($definition, 'My First StateMachine');
本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本