Рабочие процессы и машины состояний
Дата обновления перевода 2024-07-29
Рабочие процессы и машины состояний
Рабочие процессы
Рабочий процесс - это модель процесса в вашем приложении. Это может быть процесс того, как пост блога проходит этапы от черновика, до рецензии, до публикации. Другой пример - когда пользователь отправляет несколько разных форм для выполнения задачи. Такие процессы лучше всего держать подальше от ваших моделей, и стоит определять в конфигурации.
Определение рабочего процесса состоит из мест и действий, которые нужно переместить из одного места в другое. Эти действия называются переходами. Рабочий процесс также должен знать местоположение каждого объекта в рабочем процессе. Хранилище маркировки записывает текущее место в свойство объекта.
Note
Терминология выше часто используется при обсуждении рабочих процессов и сетей Петри
Примеры
Самый простой рабочий процесс выглядит так. Он содержит два места и один переход.
Рабочие процессы могут быть более сложными, когда они описывают реальный бизнес-пример. Рабочий процесс ниже описывает процесс заполнения заявки на работу.
Когда вы заполняете заявку на работу в этом примере, у вас будет от 4 до 7
шагов, в зависимости от того, на какую работу вы подаетесь. Некоторые виды
работы требуют тестов личности, тестов на логику и/или формальных требований,
на которые должен ответить пользователь. Некоторые - не требуют этого.
GuardEvent
используется для того, какие следующие шаги разрешены для
конкретной заявки.
Определяя рабочий процесс таким образом, существует обзор того, как выглядит процесс. Логика процесса не смешивается с контроллерами, моделями или просмотром. Порядок шагов может быть изменен только путем изменения конфигурации.
Машины состояний
Машина состояний - это подмножество рабочего процесса, целью которого является содержание состояние вашей модели. Наиболее важные различия между ними:
- Рабочие процессы могут быть больше, чем в одном месте одновременно, а машины состояний - нет;
- Для того, чтобы применить переход, рабочие процессы требуют того, чтобы объект был во всех предыдущих местах перехода, в то время как машины состояний требуют только чтобы объект был хотя бы в одном из этих мест.
Пример
Запрос на включение запускает изначальное "стартовое" состояние, а затем состояние "тестирования", для, например, выполнения тестов в непрерывном стеке интеграции. Когда оно будет закончено, запрос на включение переходит в состояние "рецензии", где можно запросить изменения, принять или отклонить запрос на включение. В любое время, вы также можете "обновить" запрос на включение, что приведет к новому запуску беспрерывной интеграции.
Ниже можно увидеть конфигурацию запроса на включение машины состояний.
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
# config/packages/workflow.yaml
framework:
workflows:
pull_request:
type: 'state_machine'
marking_store:
type: 'method'
property: 'currentPlace'
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
Tip
Вы можете опустить опцию places
, если ваши переходы определяют все места,
которые используются в рабочем процессе. Symfony автоматически извлечет места
из переходов.
7.1
Поддержка опускания опции places
была представлена в
Symfony 7.1.
Symfony автоматически создает сервис для каждого рабочего процесса (Workflow)
или машины состояний (StateMachine) , которые вы
определили в вашей конфигурации. Вы можете использовать рабочий процесс внутри класса, используя
автомонтирование сервисов и используя
camelCased workflow name + Workflow
в качестве имени параметра. Если это тип состояния
машины, используйте camelCased workflow name + 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 внедрит машину состояний 'pull_request', сконфигурированную ранее
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 валидирует рабочие процессы и машины состояний, которые определены в файлах конфигурации. Если ваши рабочие процессы или машины состояний определены программно, а не в файле конфигурации, вы можете валидировать их с помощью the 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'),
// Это дублированное событие "from" состояния "created" невалидно
new Transition('activate', 'created', 'deleted'),
new Transition('delete', 'activated', 'deleted'),
];
// При запуске валидация не проводится
$definition = new Definition($states, $stateTransitions);
$validator = new StateMachineValidator();
// Вызывает InvalidDefinitionException в случае невалидного определения
$validator->validate($definition, 'My First StateMachine');