Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия |
ru:rule:control_branch [2024-01-08 19:45] – [✘ Как НЕ надо] Anatoly Belaychuk | ru:rule:control_branch [2024-11-02 13:40] (текущий) – [✘ Как НЕ надо] Anatoly Belaychuk |
---|
====== Используйте подпроцесс и контрольный поток управления в качестве альтернативы прикрепленному обработчику ====== | ====== В качестве альтернативы прикрепленному обработчику можно использовать подпроцесс и контрольный поток управления ====== |
| |
{{tag>subprocess gateway event "attached event"}} | {{tag>подпроцесс событие прикрепленный_обработчик событие-останов}} |
| |
Для моделирования гибкой логики обработки событий используйте подпроцесс, содержащий основной и контрольный потоки управления. | Для моделирования гибкой логики обработки событий используйте подпроцесс, содержащий основной и контрольный потоки управления. |
===== ✔ Как надо ===== | ===== ✔ Как надо ===== |
| |
Предположим, вам необходимо смоделировать ожидание поступления платежа от клиента с одновременным контролем срока оплаты и, в случае просрочки, выяснением причин. Используйте для этого следующие шаги: | Предположим, вам необходимо смоделировать ожидание поступления платежа от клиента с одновременным контролем срока оплаты и, в случае просрочки, выяснением причин. |
| Для этого выполните следующие шаги: |
| |
- Поместите задачу "Получить оплату" в подпроцесс. | - Поместите задачу "Получить оплату" в подпроцесс. |
- Начните подпроцесса с параллельной развилки, из которой исходят две ветви, "рабочая" и "контрольная". | - Начните подпроцесс с параллельной развилки, из которой исходят две ветви, "рабочая" и "контрольная". |
- Разместите задачу "Получить оплату" на рабочей ветви. | - Разместите задачу "Получить оплату" на рабочей ветви. |
- Разместите таймер на контрольной ветви. | - Разместите таймер на контрольной ветви. |
===== ✘ Как НЕ надо ===== | ===== ✘ Как НЕ надо ===== |
| |
Interrupting attached timer won't let discussing the issue with client while still trying to obtain the payment: | Прерывающий прикрепленный обработчик не даст возможности выяснять у клиента причину задержки, продолжая при этом надеяться на поступление платежа: |
| |
<bpmnio type="bpmn"> | <bpmnio type="bpmn"> |
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="sid-38422fae-e03e-43a3-bef4-bd33b32041b2" targetNamespace="http://bpmn.io/bpmn" exporter="http://bpmn.io" exporterVersion="0.10.1"> | <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="sid-38422fae-e03e-43a3-bef4-bd33b32041b2" targetNamespace="http://bpmn.io/bpmn" exporter="http://bpmn.io" exporterVersion="0.10.1"> |
<process id="Process_0kf0077"> | <process id="Process_0kf0077"> |
<task id="Activity_1mnvjuz" name="Obtain payment"> | <task id="Activity_1mnvjuz" name="Получить оплату"> |
<incoming>Flow_1mqvexf</incoming> | <incoming>Flow_1mqvexf</incoming> |
<outgoing>Flow_0b5yo8b</outgoing> | <outgoing>Flow_0b5yo8b</outgoing> |
</startEvent> | </startEvent> |
<sequenceFlow id="Flow_1mqvexf" sourceRef="Event_0jid81n" targetRef="Activity_1mnvjuz" /> | <sequenceFlow id="Flow_1mqvexf" sourceRef="Event_0jid81n" targetRef="Activity_1mnvjuz" /> |
<endEvent id="Event_1k1tn88" name="Paid"> | <endEvent id="Event_1k1tn88" name="Оплачено"> |
<incoming>Flow_0b5yo8b</incoming> | <incoming>Flow_0b5yo8b</incoming> |
</endEvent> | </endEvent> |
<sequenceFlow id="Flow_0b5yo8b" sourceRef="Activity_1mnvjuz" targetRef="Event_1k1tn88" /> | <sequenceFlow id="Flow_0b5yo8b" sourceRef="Activity_1mnvjuz" targetRef="Event_1k1tn88" /> |
<boundaryEvent id="Event_0r0tew3" name="Payment due date" attachedToRef="Activity_1mnvjuz"> | <boundaryEvent id="Event_0r0tew3" name="Срок оплаты" attachedToRef="Activity_1mnvjuz"> |
<outgoing>Flow_0xmx632</outgoing> | <outgoing>Flow_0xmx632</outgoing> |
<timerEventDefinition id="TimerEventDefinition_0f85qyr" /> | <timerEventDefinition id="TimerEventDefinition_0f85qyr" /> |
</boundaryEvent> | </boundaryEvent> |
<sequenceFlow id="Flow_0xmx632" sourceRef="Event_0r0tew3" targetRef="Event_04k06ga" /> | <sequenceFlow id="Flow_0xmx632" sourceRef="Event_0r0tew3" targetRef="Event_04k06ga" /> |
<endEvent id="Event_04k06ga" name="Not paid"> | <endEvent id="Event_04k06ga" name="Не оплачено"> |
<incoming>Flow_0xmx632</incoming> | <incoming>Flow_0xmx632</incoming> |
</endEvent> | </endEvent> |
</bpmnio> | </bpmnio> |
| |
Non-interrupting looks better but it won't let resetting the timer to the new due date: | Непрерывающий обработчик выглядит более подходящим, но он не даст возможности установить таймер на новый срок оплаты: |
| |
<bpmnio type="bpmn"> | <bpmnio type="bpmn"> |
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="sid-38422fae-e03e-43a3-bef4-bd33b32041b2" targetNamespace="http://bpmn.io/bpmn" exporter="http://bpmn.io" exporterVersion="0.10.1"> | <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="sid-38422fae-e03e-43a3-bef4-bd33b32041b2" targetNamespace="http://bpmn.io/bpmn" exporter="http://bpmn.io" exporterVersion="0.10.1"> |
<process id="Process_0kf0077"> | <process id="Process_0kf0077"> |
<task id="Activity_1mnvjuz" name="Obtain payment"> | <task id="Activity_1mnvjuz" name="Получить оплату"> |
<incoming>Flow_1mqvexf</incoming> | <incoming>Flow_1mqvexf</incoming> |
<outgoing>Flow_0b5yo8b</outgoing> | <outgoing>Flow_0b5yo8b</outgoing> |
<sequenceFlow id="Flow_1mqvexf" sourceRef="Event_0jid81n" targetRef="Activity_1mnvjuz" /> | <sequenceFlow id="Flow_1mqvexf" sourceRef="Event_0jid81n" targetRef="Activity_1mnvjuz" /> |
<sequenceFlow id="Flow_1fkn8r9" sourceRef="Event_0r0tew3" targetRef="Activity_1skmlnn" /> | <sequenceFlow id="Flow_1fkn8r9" sourceRef="Event_0r0tew3" targetRef="Activity_1skmlnn" /> |
<endEvent id="Event_1k1tn88" name="Paid"> | <endEvent id="Event_1k1tn88" name="Оплачено"> |
<incoming>Flow_0b5yo8b</incoming> | <incoming>Flow_0b5yo8b</incoming> |
| <terminateEventDefinition id="TerminateEventDefinition_0jd5cs4" /> |
</endEvent> | </endEvent> |
<sequenceFlow id="Flow_0b5yo8b" sourceRef="Activity_1mnvjuz" targetRef="Event_1k1tn88" /> | <sequenceFlow id="Flow_0b5yo8b" sourceRef="Activity_1mnvjuz" targetRef="Event_1k1tn88" /> |
<boundaryEvent id="Event_0r0tew3" name="Payment due date" cancelActivity="false" attachedToRef="Activity_1mnvjuz"> | <boundaryEvent id="Event_0r0tew3" name="Срок оплаты" cancelActivity="false" attachedToRef="Activity_1mnvjuz"> |
<outgoing>Flow_1fkn8r9</outgoing> | <outgoing>Flow_1fkn8r9</outgoing> |
<timerEventDefinition id="TimerEventDefinition_1u44tv6" /> | <timerEventDefinition id="TimerEventDefinition_1u44tv6" /> |
</boundaryEvent> | </boundaryEvent> |
<task id="Activity_1skmlnn" name="Clarify delay with the client"> | <task id="Activity_1skmlnn" name="Выяснить у клиента причину задержки"> |
<incoming>Flow_1fkn8r9</incoming> | <incoming>Flow_1fkn8r9</incoming> |
<outgoing>Flow_0gsynar</outgoing> | <outgoing>Flow_0gsynar</outgoing> |
</task> | </task> |
<sequenceFlow id="Flow_0gsynar" sourceRef="Activity_1skmlnn" targetRef="Gateway_1sygjo0" /> | <sequenceFlow id="Flow_0gsynar" sourceRef="Activity_1skmlnn" targetRef="Gateway_1sygjo0" /> |
<exclusiveGateway id="Gateway_1sygjo0" name="Wait more?"> | <exclusiveGateway id="Gateway_1sygjo0" name="Ждать еще?"> |
<incoming>Flow_0gsynar</incoming> | <incoming>Flow_0gsynar</incoming> |
<outgoing>Flow_0jzxjdu</outgoing> | <outgoing>Flow_0jzxjdu</outgoing> |
<outgoing>Flow_16a0qq5</outgoing> | <outgoing>Flow_16a0qq5</outgoing> |
</exclusiveGateway> | </exclusiveGateway> |
<sequenceFlow id="Flow_0jzxjdu" name="no" sourceRef="Gateway_1sygjo0" targetRef="Event_04k06ga" /> | <sequenceFlow id="Flow_0jzxjdu" name="нет" sourceRef="Gateway_1sygjo0" targetRef="Event_04k06ga" /> |
<endEvent id="Event_04k06ga" name="Not paid"> | <endEvent id="Event_04k06ga" name="Не оплачено"> |
<incoming>Flow_0jzxjdu</incoming> | <incoming>Flow_0jzxjdu</incoming> |
<terminateEventDefinition id="TerminateEventDefinition_1uvti5o" /> | <terminateEventDefinition id="TerminateEventDefinition_1uvti5o" /> |
</endEvent> | </endEvent> |
<endEvent id="Event_1ltc3ao" name="Overdue"> | <endEvent id="Event_1ltc3ao" name="Платеж просрочен"> |
<incoming>Flow_16a0qq5</incoming> | <incoming>Flow_16a0qq5</incoming> |
</endEvent> | </endEvent> |
<sequenceFlow id="Flow_16a0qq5" name="yes" sourceRef="Gateway_1sygjo0" targetRef="Event_1ltc3ao" /> | <sequenceFlow id="Flow_16a0qq5" name="да" sourceRef="Gateway_1sygjo0" targetRef="Event_1ltc3ao" /> |
</process> | </process> |
<bpmndi:BPMNDiagram id="BpmnDiagram_1"> | <bpmndi:BPMNDiagram id="BpmnDiagram_1"> |
===== Примечания ===== | ===== Примечания ===== |
| |
- [[en:rule:event_gateway_warning | Exclusive event-based gateway ]] won't do the job. | - Прикрепленный обработчик разрывает логику подпроцесса: часть логики оказывается внутри подпроцесса, часть - снаружи. Рассматриваемая альтернативная техника лишена этого недостатка. |
- Although it's usually better to use [[en:rule:collapsed_subprocess | collapsed representation of a process ]] to isolate its internals, it may make sence to depict the subprocess expanded in this technique to make the logic clear. | - Как правило, предпочтительно [[ru:rule:collapsed_subprocess | изображать подпроцесс в свернутом виде ]], чтобы абстрагироваться от его внутреннего устройства, но в данном случае есть смысл показать подпроцесс развернутым, чтобы прояснить логику процесса. |
- As an exception to the [[en:rule:one_outgoing_control_flow | general rule ]], one may initiate work and control flows directly from the start event: | - Как правило, [[ru:rule:explicit_parallel_split| из действия или события не должно выходить несколько потоков управления ]], но в данном случае допустимо изобразить основную и контрольную ветви выходящими непосредственно из стартового события: |
| |
<bpmnio type="bpmn"> | <bpmnio type="bpmn"> |
<outgoing>Flow_1v8e8eg</outgoing> | <outgoing>Flow_1v8e8eg</outgoing> |
</startEvent> | </startEvent> |
<task id="Activity_1mnvjuz" name="Obtain payment"> | <task id="Activity_1mnvjuz" name="Получить оплату"> |
<incoming>Flow_1qbujp7</incoming> | <incoming>Flow_1qbujp7</incoming> |
<outgoing>Flow_0xinlw8</outgoing> | <outgoing>Flow_0xinlw8</outgoing> |
</task> | </task> |
<intermediateCatchEvent id="Event_0r0tew3" name="Payment due date"> | <intermediateCatchEvent id="Event_0r0tew3" name="Срок оплаты"> |
<incoming>Flow_0tjh6sh</incoming> | <incoming>Flow_0tjh6sh</incoming> |
<outgoing>Flow_0vj1spf</outgoing> | <outgoing>Flow_0vj1spf</outgoing> |
<sequenceFlow id="Flow_0tjh6sh" sourceRef="Gateway_1jxup79" targetRef="Event_0r0tew3" /> | <sequenceFlow id="Flow_0tjh6sh" sourceRef="Gateway_1jxup79" targetRef="Event_0r0tew3" /> |
<sequenceFlow id="Flow_0xinlw8" sourceRef="Activity_1mnvjuz" targetRef="Event_1k1tn88" /> | <sequenceFlow id="Flow_0xinlw8" sourceRef="Activity_1mnvjuz" targetRef="Event_1k1tn88" /> |
<endEvent id="Event_1k1tn88" name="Paid"> | <endEvent id="Event_1k1tn88" name="Оплачено"> |
<incoming>Flow_0xinlw8</incoming> | <incoming>Flow_0xinlw8</incoming> |
<terminateEventDefinition id="TerminateEventDefinition_0ku242o" /> | <terminateEventDefinition id="TerminateEventDefinition_0ku242o" /> |
</endEvent> | </endEvent> |
<task id="Activity_12mr8cn" name="Clarify delay with the client"> | <task id="Activity_12mr8cn" name="Выяснить у клиента причину задержки"> |
<incoming>Flow_0vj1spf</incoming> | <incoming>Flow_0vj1spf</incoming> |
<outgoing>Flow_0v7giyt</outgoing> | <outgoing>Flow_0v7giyt</outgoing> |
</task> | </task> |
<sequenceFlow id="Flow_0vj1spf" sourceRef="Event_0r0tew3" targetRef="Activity_12mr8cn" /> | <sequenceFlow id="Flow_0vj1spf" sourceRef="Event_0r0tew3" targetRef="Activity_12mr8cn" /> |
<exclusiveGateway id="Gateway_0gfb7mo" name="Wait more?"> | <exclusiveGateway id="Gateway_0gfb7mo" name="Ждать еще?"> |
<incoming>Flow_0v7giyt</incoming> | <incoming>Flow_0v7giyt</incoming> |
<outgoing>Flow_0xssdyb</outgoing> | <outgoing>Flow_0xssdyb</outgoing> |
</exclusiveGateway> | </exclusiveGateway> |
<sequenceFlow id="Flow_0v7giyt" sourceRef="Activity_12mr8cn" targetRef="Gateway_0gfb7mo" /> | <sequenceFlow id="Flow_0v7giyt" sourceRef="Activity_12mr8cn" targetRef="Gateway_0gfb7mo" /> |
<sequenceFlow id="Flow_0xssdyb" name="no" sourceRef="Gateway_0gfb7mo" targetRef="Event_04k06ga" /> | <sequenceFlow id="Flow_0xssdyb" name="нет" sourceRef="Gateway_0gfb7mo" targetRef="Event_04k06ga" /> |
<sequenceFlow id="Flow_1fpmuu7" name="yes" sourceRef="Gateway_0gfb7mo" targetRef="Gateway_1jxup79" /> | <sequenceFlow id="Flow_1fpmuu7" name="да" sourceRef="Gateway_0gfb7mo" targetRef="Gateway_1jxup79" /> |
<endEvent id="Event_04k06ga" name="Not paid"> | <endEvent id="Event_04k06ga" name="Не оплачено"> |
<incoming>Flow_0xssdyb</incoming> | <incoming>Flow_0xssdyb</incoming> |
<terminateEventDefinition id="TerminateEventDefinition_0jd5cs4" /> | <terminateEventDefinition id="TerminateEventDefinition_0jd5cs4" /> |
</definitions> | </definitions> |
</bpmnio> | </bpmnio> |
===== Исключения ===== | ===== Смотри также ===== |
| |
Attached events are simpler and hence should be preferred in more straightforward scenarios. | |
| |
| * [[ru:rule:event_gateway_warning]] |
===== Автор(ы) ===== | ===== Автор(ы) ===== |
| |
--- //[[user:bell|Anatoly Belaychuk]] 2024-01-08 18:53// | --- //[[user:bell|Anatoly Belaychuk]] 2024-01-08 18:53// |