Заявление об авторских правах: эта статья является оригинальной статьей блоггера и не может быть воспроизведена без разрешения блоггера. Обратите внимание на публичный аккаунтОбмен технологиями (ID: jishuhui_2015)Связаться с автором можно.
Введение
С макро точки зрения "система рабочих заданий" представляет собой переход некоторых потоков состояний. Автор считает, что реализация системы рабочих заданий - это реализация рабочего процесса. Типичные приложения включают корпоративные системы открытого доступа, различные CRM, ERP и т. д. . . .
Для реализации системы заказов на работу вы можете написать соответствующий бизнес-код в сочетании с реальным бизнесом.Самое большое преимущество этого заключается в том, что степень настройки высока, а работающий бизнес-процесс сильно настраивается. Однако верно и обратное, и сильно настроенные бизнес-процессы теряют некоторую гибкость.
Вот и возникает вопрос: как балансировать?
Ответ: на основе отраслевых стандартов.
Стандарт = Авторитет
Когда мы обнаруживаем, что разработанный бизнес-процесс не соответствует стандарту, нам приходится в этом сомневаться.
Настало время изменить себя в рабочем процессе «Убийца»: BPMN2.0
Что касается основного введения в BPMN2.0, я не буду повторять его здесь, а резюмирую в одном предложении: BPMN2.0 — это полный набор стандартов разработки рабочих процессов, сформулированных IBM, который включает в себя события, шлюзы, потоки операций, задачи, и т.д. Базовый элемент класса.
В конце концов, BPMN2.0 — это всего лишь набор стандартов, которые необходимо внедрить.Известная среда разработки рабочих процессов в отрасли — Activiti.Используемый язык программирования — Java, который широко используется.Если рабочий процесс используется в реальной работе , вы можете использовать эту среду разработки, если основная среда разработки не является Java, вы можете делать только свои собственные колеса.
Если вы собираетесь заняться разработкой рабочего процесса, будь то использование фреймворка или самостоятельное исследование, рекомендуется прочитать егоэтот документ, очень полезно для фактической разработки.
Возвращаясь к «системе заказов», упомянутой в начале статьи, я расскажу о некоторых личных мыслях автора при запуске этого проекта.
Продвижение процесса самого заказа на работу является проявлением рабочего процесса, поэтому естественно использовать стандарт BPMN2.0. На изучение вышеупомянутых справочных документов ушло около рабочего дня, и я все больше чувствовал, что тонкостей стандарта BPMN2.0 более чем достаточно для покрытия существующих бизнес-требований.
Конечно, при создании системной архитектуры она должна сочетаться с реальными потребностями бизнеса. Я тщательно проанализировал свои собственные бизнес-потребности и обнаружил, что все они являются «короткими процессами».Там не более 2 рабочих заданий, только один тип рабочего задания (т.е. userTask) и не так много ветвей процесса. , автор Они сталкиваются с некоторыми относительно простыми процессами заказа на работу.
Если вы непосредственно используете огромный и сложный фреймворк типа Авити, с одной стороны, собственно процесс заказа на работу не сложен, с другой стороны, он подозревается в излишестве, и члены команды не знакомы с этим стандартом, поэтому сложно понять и подключить.
Поэтому автор встал на путь самоисследования на основе стандарта BPMN2.0.
Дело не в стремлении перестроить Activiti, а в том, чтобы адаптировать функции Activiti и внедрить только некоторые необходимые стандарты.
Архитектурный дизайн этой системы рабочих заданий будет объяснен в трех статьях, в этой статье основное внимание будет уделено элементам стандарта BPMN2.0, которые я использовал.
2. Язык определения рабочего процесса (WDL)
Язык определения рабочего процесса (далее WDL), что означает «Язык определения рабочего процесса», является личным творением, а не официальным термином, а просто предназначен для унификации языка внутри команды.
Следуя за дизайном и реализацией Activiti, WDL также основан на XML.
В системе нарядов на работу автор реализует следующие 8 основных элементов:
Компоненты WDL описаны ниже:1. Корневой узел, состоящий из пары меток определений..
<definitions id="def" name="工作流程配置"> </definitions>
2,Узел определения процесса, представленный парой вкладок процесса, его дочерние узлы в полном процессе. 值得一提的是,BPMN2.0标准中是允许subProcess(子流程)存在的,这个feature在此工单系统里并未实现。
<process id="verify_work" name="用户审核流程"> </process>
3, пустые узлы начальных событий, обычно представляют собой начало процесса.
<startEvent id="start" name="开始事件"/>
4. Определение временных событий не может существовать само по себе.Эффект заключается в добавлении таймера на основе других событий.Типичным применением является упомянутое ниже синхронизированное граничное событие..
<timerEventDefinition>
<!-- 时间点 或者 cron表达式 -->
<timeDuration>${duration}</timeDuration>
</timerEventDefinition>
5. Приуроченные граничные события.
События границы захвачены событием, оно будет прикреплено к узлу, когда узел работает, прослушиватель событий, соответствующий типу триггера. Когда граничное событие будет зафиксировано, узел прервет операцию, выполняя последующий процесс события.
Граничное событие с ограничением по времени можно рассматривать как часы, которые останавливаются для предупреждения. Когда выполнение процесса достигает ссылки, привязанной к граничному событию, запускается таймер.
Когда таймер срабатывает, связь прерывается, и выполнение продолжается по исходящему проводу синхронизированного граничного события.
<boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="userTask">
<!-- cancelActivity表示是否会中断边界事件所依附的任务 -->
<timerEventDefinition>
<timeDuration>0 15 10 * * ? *</timeDuration>
</timerEventDefinition>
</boundaryEvent>
6. Сообщения (границы) событий, прием и отправка сообщений должны быть реализованы на уровне приложения или архитектуры, а в него встроен движок процесса.
Этот элемент изменился по сравнению со стандартным. Событие сообщения определяется как средство уведомления обратного вызова в системе заказов на работу.Существует два типа уведомлений: REST и MQ.Параметры, переносимые уведомлением, могут быть определены в параметрах, а имя — это имя параметра.
Тег сообщения — это единственный тег на том же уровне, что и тег процесса.Сообщение похоже на глобальную переменную, на которую могут ссылаться несколько элементов в WDL.
Следующее определяет тело сообщения и ссылается на него в событии границы сообщения.
<message id="newInvoice" name="newInvoiceMessage" type="REST | MQ">
<params>
<param name="target">${target}</param>
<param name="a">${a}</param>
<param name="x">${x}</param>
</params>
</message>
<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true">
<messageEventDefinition messageRef="newInvoice"/>
</boundaryEvent>
7. Узел последовательного процесса представляет собой стрелку в одном направлении в виде выражения, поэтому вам нужно определить элементы на обоих концах. начальный элементsourceRefОпределение атрибута, указывающее на элемент сtargetRefОпределение атрибута, значение которого является значением атрибута id элемента. Также видно, что основные элементы в потоке последовательности обычно нужно идентифицировать по атрибуту id, и лучше не повторять их, чтобы избежать путаницы.
<sequenceFlow id="flow1" sourceRef="ss" targetRef="tt" />
8. Условный узел процесса, означающий, что определенное условие приводит к соответствующему потоку последовательности..
<sequenceFlow id="flow1" sourceRef="exclusiveGw" targetRef="task1">
<conditionExpression>${condition}</conditionExpression>
</sequenceFlow>
9. Пользовательские задачи, которые представляют собой узлы задач, требующие фактической работы персонала для продвижения..
В стандарте BPMN2.0 существует множество типов задач, таких как задачи сценариев, задачи службы Java, почтовые задачи и т. д. Activiti также расширяет задачи Mule, задачи Camel и т. д.
В системе рабочих заданий вам нужно только использовать пользовательские задачи и другие события для удовлетворения потребностей бизнеса.
<userTask id="task" name="verify_task"/>
10. Узел эксклюзивного шлюза, как и решение программы «если-иначе», соединяет множество ветвей эксклюзивного шлюза и в конце будет идти только к одной из ветвей..
<exclusiveGateway id="xgid" name="Request approved" default="sf"/> <!-- default表示默认流程 -->
11. Узел шлюза параллелизма противоположен эксклюзивному шлюзу, и многие ветви, соединяющие шлюз параллелизма, будут выполняться одновременно..
<parallelGateway id="pgid" name="gname"/>
12. Пустой узел конечного события, обычно как конец процесса.
<endEvent id="end" name="结束事件"/>
Дополнительные инструкции:
В вышеупомянутых временных событиях, определениях сообщений, потоке последовательности и других элементах используется один и тот же метод значений, то есть наша общая форма ${value} не использует методы анализа, связанные с пружинами, а вдохновлена Activiti.JUELИнструменты анализируют и выполняют выражения.
В WDL не нужны слишком сложные выражения, достаточно поддерживать простые значения и логические операции, такие как: ${name}, ${approved==true}.
Три, пример объяснения
Чтобы углубить понимание вышеупомянутых элементов, автор выбрал 5 репрезентативных примеров, чтобы показать содержание их WDL.этот документ.
Следует отметить, что подузлы в определениях не обращают внимания на порядок, и нет необходимости писать WDL в соответствии с направлением процесса. Личная привычка состоит в том, чтобы сначала определить элементы узла, а затем использовать поток последовательности (sequenceFlow) для соединения.
Этот случай относительно прост, только с одним начальным узлом и одним узлом задачи.
<definitions id="def" name="工作流程配置">
<process id="verifyCredit" name="verify credit">
<startEvent id="start" name="开始"/>
<userTask id="unkown" name=""/>
<sequenceFlow id="flow1" sourceRef="start" targetRef="unkown">
<conditionExpression>${condition}</conditionExpression>
</sequenceFlow>
</process>
</definitions>
Это типичный одноветвевой последовательный процесс.
<definitions id="def" name="工作流程配置">
<process id="pid" name="my process">
<startEvent id="start" name="开始"/>
<userTask id="write" name="Write monthly financial report"/>
<userTask id="verify" name="Verify monthly financial report"/>
<sequenceFlow id="flow1" sourceRef="start" targetRef="write"/>
<sequenceFlow id="flow2" sourceRef="write" targetRef="verify"/>
<sequenceFlow id="flow2" sourceRef="verify" targetRef="end"/>
<endEvent id="end"/>
</process>
</definitions>
Здесь возникает ситуация с несколькими ветвями, и определяется поток по умолчанию, аналогичный следующему:
if (conditionA) {
doTask1
} else if (conditionB) {
doTask3
} else {
doTask2
}
Нетрудно заметить, что эксклюзивный шлюз обычно сопровождается потоком по умолчанию, а следующее содержимое WDL.
<definitions id="def" name="工作流程配置">
<process id="pid" name="my process">
<startEvent id="start" name="开始"/>
<userTask id="t1" name="Task1"/>
<userTask id="t2" name="Task2"/>
<userTask id="t3" name="Task3"/>
<exclusiveGateway id="xgid" name="Exclusive Gateway" default="t2"/>
<sequenceFlow id="flow1" sourceRef="xgid" targetRef="t1">
<conditionExpression>${conditionA}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow2" sourceRef="xgid" targetRef="t2"/>
<sequenceFlow id="flow1" sourceRef="xgid" targetRef="t3">
<conditionExpression>${conditionB}</conditionExpression>
</sequenceFlow>
</process>
</definitions>
На данный момент вы можете увидеть полное определение процесса с началом и концом, различными узлами задач и ветвями.
<definitions id="def" name="工作流程配置">
<process id="verifyCredit" name="verify credit">
<startEvent id="start" name="开始"/>
<userTask id="verifyCreditHistory" name="Verify credit history"/>
<sequenceFlow id="verify_flow" sourceRef="start" targetRef="verifyCreditHistory"/>
<exclusiveGateway id="approve" name="approve or not"/>
<sequenceFlow id="end_flow" sourceRef="verifyCreditHistory" targetRef="approve">
<userTask id="contact" name="Contact customer for further information"/>
<sequenceFlow id="disapprove_flow" sourceRef="approve" targetRef="contact">
<conditionExpress>${approve==false}</conditionExpress>
</sequenceFlow>
<sequenceFlow id="end_flow" sourceRef="contact" targetRef="end1">
<endEvent id="end1"/>
<sequenceFlow id="approve_flow" sourceRef="contact" targetRef="end2">
<conditionExpress>${approve==true}</conditionExpress>
</sequenceFlow>
<endEvent id="end2"/>
</process>
</definitions>
Эта ситуация включает граничное событие с ограничением по времени. Если cancelActivity="false" ситуация усложняется, так как есть два конечных узла. Когда cancelActivity="true" заканчивается только в одном месте.
<definitions id="def" name="工作流程配置">
<process id="verifyCredit" name="verify credit">
<startEvent id="start" name="开始"/>
<userTask id="firstLineSupport" name="First line support"/>
<boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="firstLineSupport">
<timerEventDefinition>
<timeDuration>2017-02-12 12:00:00</timeDuration>
</timerEventDefinition>
</boundaryEvent>
<sequenceFlow id="flow1" sourceRef="start" targetRef="firstLineSupport"/>
<sequenceFlow id="flow2" sourceRef="firstLineSupport" targetRef="end1"/>
<endEvent id="end1"/>
<userTask id="secondLineSupport" name="Second line support"/>
<sequenceFlow id="flow3" sourceRef="firstLineSupport" targetRef="secondLineSupport"/>
<sequenceFlow id="flow4" sourceRef="secondLineSupport" targetRef="end2"/>
<endEvent id="end2"/>
</process>
</definitions>
На этом этапе объясняются базовые знания, необходимые для системы рабочих заданий. В целом, BPMN 2.0 проста и понятна, она может охватывать большинство процессов заказа на работу и имеет смысл стать отраслевым стандартом.