轻量级工作流引擎的设计与实现

一、什么是工作流引擎

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:e7262421-b799-434a-ba95-a560fbf8a3cc

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:438e8713-5bc5-4eff-b891-74dc49ba21b0

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:416647c7-90c9-4455-9f4d-4671468f3c3e

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:a8917a28-52f8-4055-96e1-0e351f767026

二、为什么要重复造轮子

开源的工作流引擎很多,比如 activiti、flowable、Camunda 等,那么,为什么没有选它们呢?基于以下几点考虑:

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:fb51dea5-f13c-4f7d-bda9-3e175350df96

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:47d1e07b-dde9-40f5-acca-5f202d69836a

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:65d7085a-513c-43ae-a2fc-ade2996a5cd6

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:addf5cb4-fa93-46a7-be11-f76e5353a816

* 资料、代码量、API繁多,学习成本较高,维护性较差。
* 经过分析与评估,我们的业务场景需要的BPMN元素较少,开发实现的代价不大。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:b58877aa-3a04-47e6-a0fd-fb13f96c857a

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:19b9d6b2-1358-405d-8ae9-66f58c6e9765

三、怎么造的轮子

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:fdcb7e56-43a6-4ed3-8a6d-9e4bfb00cf72

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:f6e41b59-ffce-4108-bef2-30bf70eff247

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:132b6292-88c3-4fec-8480-27fb76e8bee3

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c0359f88-6be6-431a-b4da-cc4092b4d839

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:62ce0c27-2e1e-41e0-a879-cba81b7b46fc

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:f1eec790-5403-4703-adbe-b2be2d945ded

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:1658c217-0b65-497c-8ca0-066acb21e508

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:b237665d-7d18-4640-90ec-78dda070c208

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:e17df435-81c7-4a8a-8092-3d7f610ff6de

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:021a6f8d-3d61-425c-a57e-f4a3a3768453

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:1d58a434-cce2-45bc-a885-1417d5dc2fc1

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c2efb696-a10c-4e02-b919-b9635cf6a539

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:71982431-a730-4a3e-a34f-e2b25ecca971

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:1945dd1c-a375-424f-8512-7786d9ad0271

  • 少依赖:代码的java实现上,除了jdk8以外,不依赖与其他第三方jar包,从而可以更好的减少依赖带来的问题。
    [TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c0b0f0a9-2352-46db-b85b-105a682e03ae
    [En]

    [TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:20dd3fe2-02de-4f9c-a568-ec80471d1e94

  • 轻规范:并没有完全实现BPMN规范,也没有完全按照BPMN规范进行设计,而只是参考了该规范,且只实现以一小部分必须实现的元素。从而降低了学习成本,可以按照需求自由发挥。
  • 工具化:代码上,只是一个工具(UTIL),不是一个应用程序。从而你可以简单的运行它,扩展你自己的数据层、节点层,更加方便的集成到其他应用中去。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:92ebcee9-16bc-45be-a4b6-63122c73bc13

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c270e6e9-142b-4fd7-a92a-9207e0215e02

四、Hello ProcessEngine

按照国际惯例,第一个迭代用来实现 hello world 。

1、需求

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:2bdfe1bb-4324-479a-aa2e-b302d0992f38

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:a6c95fd6-72ff-4e82-9ff2-0ed0f6411bd9

2、分析

  • 第一个流程,可以打印Hello ProcessEngine,第二个流程可以打印ProcessEngine Hello,这两个流程的区别是只有顺序不同,蓝色的节点与红色的节点的本身功能没有发生变化
  • 蓝色的节点与红色的节点都是节点,它们的功能是不一样的,即:红色的节点打印Hello,蓝色的节点打印ProcessEngine
    [TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:9b6d8125-dc3e-49a1-87e0-f24c14e5eaab
    [En]

    [TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:819e54b1-a573-4f9c-b027-3f39473361f4

    [TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:34f432c8-24e8-4fca-8bde-3beeb73ca284

    [En]

    [TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:2be957f6-8b32-4c5c-9d22-2eb9b2e3e222

  • 需要一种表示流程的方式,或是XML、或是JSON、或是其他,而不是图片

3、设计

(1)流程的表示

相较于JSON,XML的语义更丰富,可以表达更多的信息,因此这里使用XML来对流程进行表示,如下所示

<span class="hljs-tag"><<span class="hljs-name">definitions>
    <span class="hljs-tag"><<span class="hljs-name">process <span class="hljs-attr">id=<span class="hljs-string">"process_1" <span class="hljs-attr">name=<span class="hljs-string">"hello">
        <span class="hljs-tag"><<span class="hljs-name">startEvent <span class="hljs-attr">id=<span class="hljs-string">"startEvent_1">
            <span class="hljs-tag"><<span class="hljs-name">outgoing>flow_1<span class="hljs-tag">outgoing>
        <span class="hljs-tag">startEvent>
        <span class="hljs-tag"><<span class="hljs-name">sequenceFlow <span class="hljs-attr">id=<span class="hljs-string">"flow_1" <span class="hljs-attr">sourceRef=<span class="hljs-string">"startEvent_1" <span class="hljs-attr">targetRef=<span class="hljs-string">"printHello_1" />
        <span class="hljs-tag"><<span class="hljs-name">printHello <span class="hljs-attr">id=<span class="hljs-string">"printHello_1" <span class="hljs-attr">name=<span class="hljs-string">"hello">
            <span class="hljs-tag"><<span class="hljs-name">incoming>flow_1<span class="hljs-tag">incoming>
            <span class="hljs-tag"><<span class="hljs-name">outgoing>flow_2<span class="hljs-tag">outgoing>
        <span class="hljs-tag">printHello>
        <span class="hljs-tag"><<span class="hljs-name">sequenceFlow <span class="hljs-attr">id=<span class="hljs-string">"flow_2" <span class="hljs-attr">sourceRef=<span class="hljs-string">"printHello_1" <span class="hljs-attr">targetRef=<span class="hljs-string">"printProcessEngine_1" />
        <span class="hljs-tag"><<span class="hljs-name">printProcessEngine <span class="hljs-attr">id=<span class="hljs-string">"printProcessEngine_1" <span class="hljs-attr">name=<span class="hljs-string">"processEngine">
            <span class="hljs-tag"><<span class="hljs-name">incoming>flow_2<span class="hljs-tag">incoming>
            <span class="hljs-tag"><<span class="hljs-name">outgoing>flow_3<span class="hljs-tag">outgoing>
        <span class="hljs-tag">printProcessEngine>
        <span class="hljs-tag"><<span class="hljs-name">sequenceFlow <span class="hljs-attr">id=<span class="hljs-string">"flow_3" <span class="hljs-attr">sourceRef=<span class="hljs-string">"printProcessEngine_1" <span class="hljs-attr">targetRef=<span class="hljs-string">"endEvent_1"/>
        <span class="hljs-tag"><<span class="hljs-name">endEvent <span class="hljs-attr">id=<span class="hljs-string">"endEvent_1">
            <span class="hljs-tag"><<span class="hljs-name">incoming>flow_3<span class="hljs-tag">incoming>
        <span class="hljs-tag">endEvent>
    <span class="hljs-tag">process>
<span class="hljs-tag">definitions></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
  • process表示一个流程
  • startEvent表示开始节点,endEvent表示结束节点
  • printHello表示打印hello节点,就是需求中的蓝色节点
  • processEngine表示打印processEngine节点,就是需求中的红色节点
  • sequenceFlow表示连线,从sourceRef开始,指向targetRef,例如:flow_3,表示一条从printProcessEngine_1到endEvent_1的连线。

(2)节点的表示

  • outgoing表示出边,即节点执行完毕后,应该从那个边出去。
  • incoming表示入边,即从哪个边进入到本节点。
  • 一个节点只有outgoing而没有incoming,如:startEvent,也可以 只有入边而没有出边,如:endEvent,也可以既有入边也有出边,如:printHello、processEngine。

(3)流程引擎的逻辑

基于上述XML,流程引擎的运行逻辑如下

  1. 找到开始节点(startEvent)
  2. 找到startEvent的outgoing边(sequenceFlow)
  3. 找到该边(sequenceFlow)指向的节点(targetRef)
  4. 执行节点自身的逻辑
  5. 找到该节点的outgoing边(sequenceFlow)
  6. 重复3-5,直到遇到结束节点(endEvent),流程结束

4、实现

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:177cdfe7-11e7-4713-9670-dd4666ca47ed

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:dac04005-5991-4e97-9249-9925077f6fe1

可以看到,一个流程(PeProcess)由多个节点(PeNode)与边(PeEdge)组成,节点有出边(out)、入边(in),边有流入节点(from)、流出节点(to)。

具体的定义如下:

<span class="hljs-keyword">public <span class="hljs-keyword">class PeProcess {
    <span class="hljs-keyword">public <span class="hljs-built_in">String id;
    <span class="hljs-keyword">public PeNode start;

    <span class="hljs-keyword">public PeProcess(<span class="hljs-built_in">String id, PeNode start) {
        <span class="hljs-keyword">this.id = id;
        <span class="hljs-keyword">this.start = start;
    }
}

<span class="hljs-keyword">public <span class="hljs-keyword">class PeEdge {
    <span class="hljs-keyword">private <span class="hljs-built_in">String id;
    <span class="hljs-keyword">public PeNode <span class="hljs-keyword">from;
    <span class="hljs-keyword">public PeNode to;

    <span class="hljs-keyword">public PeEdge(<span class="hljs-built_in">String id) {
        <span class="hljs-keyword">this.id = id;
    }
}

<span class="hljs-keyword">public <span class="hljs-keyword">class PeNode {
    <span class="hljs-keyword">private <span class="hljs-built_in">String id;

    <span class="hljs-keyword">public <span class="hljs-built_in">String <span class="hljs-keyword">type;
    <span class="hljs-keyword">public PeEdge <span class="hljs-keyword">in;
    <span class="hljs-keyword">public PeEdge out;

    <span class="hljs-keyword">public PeNode(<span class="hljs-built_in">String id) {
        <span class="hljs-keyword">this.id=id;
    }
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

PS : 为了表述主要思想,在代码上比较”奔放自由”,生产中不可直接复制粘贴!

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:89489d1c-de6d-4cbb-941a-9793463bd955

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:656ad7b2-3ffd-42e3-8adc-327d3384bf98

<span class="hljs-keyword">public <span class="hljs-keyword">class <span class="hljs-title">XmlPeProcessBuilder {
    <span class="hljs-keyword">private String xmlStr;
    <span class="hljs-keyword">private final Map<string, penode> id2PeNode = <span class="hljs-keyword">new HashMap<>();
    <span class="hljs-keyword">private final Map<string, peedge> id2PeEdge = <span class="hljs-keyword">new HashMap<>();

    <span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-title">XmlPeProcessBuilder(<span class="hljs-params">String xmlStr) {
        <span class="hljs-keyword">this.xmlStr = xmlStr;
    }

    <span class="hljs-function"><span class="hljs-keyword">public PeProcess <span class="hljs-title">build(<span class="hljs-params">) throws Exception {
        </span></span></span></span></span></span></span></span></span></span></string,></span></span></string,></span></span></span></span></span>

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:ed8b94ac-4a77-4e9d-8a7b-e24c4307fccf

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:3dea5259-4681-4e19-8160-6ae52d711146

<span class="hljs-keyword">public <span class="hljs-keyword">class <span class="hljs-title">ProcessEngine {
    <span class="hljs-keyword">private String xmlStr;

    <span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-title">ProcessEngine(<span class="hljs-params">String xmlStr) {
        <span class="hljs-keyword">this.xmlStr = xmlStr;
    }

    <span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">void <span class="hljs-title">run(<span class="hljs-params">) throws Exception {
        PeProcess peProcess = <span class="hljs-keyword">new XmlPeProcessBuilder(xmlStr).build();

        PeNode node = peProcess.start;
        <span class="hljs-keyword">while (!node.type.<span class="hljs-keyword">equals(<span class="hljs-string">"endEvent")) {
            <span class="hljs-keyword">if (<span class="hljs-string">"printHello".<span class="hljs-keyword">equals(node.type))
                System.<span class="hljs-keyword">out.print(<span class="hljs-string">"Hello ");
            <span class="hljs-keyword">if (<span class="hljs-string">"printProcessEngine".<span class="hljs-keyword">equals(node.type))
                System.<span class="hljs-keyword">out.print(<span class="hljs-string">"ProcessEngine ");

            node = node.<span class="hljs-keyword">out.to;
        }
    }
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

就这?工作流引擎就这?同学们可千万不要这样简单理解啊,毕竟这还只是hello world而已,各种代码量就已经不少了。

另外,这里面还有很多可以改进的空间,比如异常控制、泛化、设计模式等,但毕竟只是一个hello world而已,其目的是方便同学理解,让同学入门。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:28cbf83a-1e6d-4fdb-b7a2-cb7cad509789

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:89bb0385-a523-4a0d-86ac-023d42778371

五、简单审批

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:87db4086-89c0-4b1d-bec0-b614ee2d9eee

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:b22f8ee6-22b3-4522-8680-d2ff257d4598

1、需求

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:4c19c0d0-8b35-4297-a88c-e3024081133c

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:950ab414-3ba8-4416-9fbd-540215b4fe6c

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:f58b789c-39e3-40e8-9431-1b0b9517fb10

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:39ca348c-4a6b-46a7-aa75-9427f100257c

2、分析

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:254818ba-c424-4045-8497-fbb4c5965c51

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:3da67220-5a8a-4b7c-a230-aa06a6cfd116

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:342cde92-22eb-48cf-9df2-d56a49b7b935

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:b4fd85b3-7916-4431-9c2c-3748ea350660

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:584df568-794d-4821-ae89-a9d6f4a0a311

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:7171d46a-e0ad-43af-a747-c9d66b98e5ff

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:7260c082-4690-4e61-ae90-f5f6730e2b31

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:1dc8e3c3-41e3-4397-a7dd-aacbd0da04fc

3、设计

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:d66c8083-79a7-49d4-b562-493861bc266f

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:48b13c23-bdc5-4339-b759-5b05c28964dc

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:a121600a-ba65-43de-b7e2-900d00bcb0b8

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:190bd298-8167-4a39-bf86-e29ac0ea7403

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:972f747e-2b90-4b3d-a03a-1a5c618f5579

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c0ee4499-139f-4f83-a57e-6d25b10337cd

4、实现

新的XML定义如下:

<span class="hljs-tag"><<span class="hljs-name">definitions>
    <span class="hljs-tag"><<span class="hljs-name">process <span class="hljs-attr">id=<span class="hljs-string">"process_2" <span class="hljs-attr">name=<span class="hljs-string">"&#x7B80;&#x5355;&#x5BA1;&#x6279;&#x4F8B;&#x5B50;">
        <span class="hljs-tag"><<span class="hljs-name">startEvent <span class="hljs-attr">id=<span class="hljs-string">"startEvent_1">
            <span class="hljs-tag"><<span class="hljs-name">outgoing>flow_1<span class="hljs-tag">outgoing>
        <span class="hljs-tag">startEvent>
        <span class="hljs-tag"><<span class="hljs-name">sequenceFlow <span class="hljs-attr">id=<span class="hljs-string">"flow_1" <span class="hljs-attr">sourceRef=<span class="hljs-string">"startEvent_1" <span class="hljs-attr">targetRef=<span class="hljs-string">"approvalApply_1" />
        <span class="hljs-tag"><<span class="hljs-name">approvalApply <span class="hljs-attr">id=<span class="hljs-string">"approvalApply_1" <span class="hljs-attr">name=<span class="hljs-string">"&#x63D0;&#x4EA4;&#x7533;&#x8BF7;&#x5355;">
            <span class="hljs-tag"><<span class="hljs-name">incoming>flow_1<span class="hljs-tag">incoming>
            <span class="hljs-tag"><<span class="hljs-name">outgoing>flow_2<span class="hljs-tag">outgoing>
        <span class="hljs-tag">approvalApply>
        <span class="hljs-tag"><<span class="hljs-name">sequenceFlow <span class="hljs-attr">id=<span class="hljs-string">"flow_2" <span class="hljs-attr">sourceRef=<span class="hljs-string">"approvalApply_1" <span class="hljs-attr">targetRef=<span class="hljs-string">"approval_1" />
        <span class="hljs-tag"><<span class="hljs-name">approval <span class="hljs-attr">id=<span class="hljs-string">"approval_1" <span class="hljs-attr">name=<span class="hljs-string">"&#x5BA1;&#x6279;">
            <span class="hljs-tag"><<span class="hljs-name">incoming>flow_2<span class="hljs-tag">incoming>
            <span class="hljs-tag"><<span class="hljs-name">outgoing>flow_3<span class="hljs-tag">outgoing>
        <span class="hljs-tag">approval>
        <span class="hljs-tag"><<span class="hljs-name">sequenceFlow <span class="hljs-attr">id=<span class="hljs-string">"flow_3" <span class="hljs-attr">sourceRef=<span class="hljs-string">"approval_1" <span class="hljs-attr">targetRef=<span class="hljs-string">"notify_1"/>
        <span class="hljs-tag"><<span class="hljs-name">notify <span class="hljs-attr">id=<span class="hljs-string">"notify_1" <span class="hljs-attr">name=<span class="hljs-string">"&#x7ED3;&#x679C;&#x90AE;&#x4EF6;&#x901A;&#x77E5;">
            <span class="hljs-tag"><<span class="hljs-name">incoming>flow_3<span class="hljs-tag">incoming>
            <span class="hljs-tag"><<span class="hljs-name">outgoing>flow_4<span class="hljs-tag">outgoing>
        <span class="hljs-tag">notify>
        <span class="hljs-tag"><<span class="hljs-name">sequenceFlow <span class="hljs-attr">id=<span class="hljs-string">"flow_4" <span class="hljs-attr">sourceRef=<span class="hljs-string">"notify_1" <span class="hljs-attr">targetRef=<span class="hljs-string">"endEvent_1"/>
        <span class="hljs-tag"><<span class="hljs-name">endEvent <span class="hljs-attr">id=<span class="hljs-string">"endEvent_1">
            <span class="hljs-tag"><<span class="hljs-name">incoming>flow_4<span class="hljs-tag">incoming>
        <span class="hljs-tag">endEvent>
    <span class="hljs-tag">process>
<span class="hljs-tag">definitions></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:45004816-e26f-4d7a-b17b-543d4aae68e1

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:8331879a-5e07-4ac7-b3b6-66e45995a835

<span class="hljs-keyword">public <span class="hljs-keyword">class <span class="hljs-title">PeContext {
    <span class="hljs-keyword">private Map<string, object> info = <span class="hljs-keyword">new ConcurrentHashMap<>();

    <span class="hljs-function"><span class="hljs-keyword">public Object <span class="hljs-title">getValue(<span class="hljs-params">String key) {
        <span class="hljs-keyword">return info.<span class="hljs-keyword">get(key);
    }

    <span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">void <span class="hljs-title">putValue(<span class="hljs-params">String key, Object <span class="hljs-keyword">value) {
        info.put(key, <span class="hljs-keyword">value);
    }
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></string,></span></span></span></span>

每个节点的处理逻辑是不一样的,此处应该进行一定的抽象,为了强调流程中节点的作用是逻辑处理,引入了一种新的类型–算子(Operator),定义如下:

<span class="hljs-keyword">public <span class="hljs-keyword">interface <span class="hljs-title">IOperator {
    </span></span></span>

对于引擎来讲,当遇到一个节点时,需要调度之,但怎么调度呢?首先需要各个节点算子注册(registNodeProcessor())进来,这样才能找到要调度的那个算子。

其次,引擎怎么知道节点算子自有逻辑处理完了呢?一般来讲,引擎是不知道的,只能是由算子告诉引擎,所以引擎要提供一个功能(nodeFinished()),这个功能由算子调用。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:508566b6-0ae8-4883-922f-7ccb56f4d24f

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:a296e89a-7204-42b9-8f40-dd176267b2c0

修改后的ProcessEngine代码如下:

<span class="hljs-keyword">public <span class="hljs-keyword">class <span class="hljs-title">ProcessEngine {
    <span class="hljs-keyword">private String xmlStr;

    </span></span></span></span>

接下来,简单(简陋)实现本示例所需的三个算子,代码如下:

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:7218ecda-4480-4e25-8c36-7007627728eb

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:744834e3-3448-482b-bb63-5e9c2f44b59d

<span class="hljs-keyword">public <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">ProcessEngineTest {

    </span></span></span></span>

到此,轻量级工作流引擎的核心逻辑介绍的差不多了,然而,只支持顺序结构是太单薄的,我们知道,程序流程的三种基本结构为顺序、分支、循环,有了这三种结构,基本上就可以表示绝大多数流程逻辑。循环可以看做一种组合结构,即:循环可以由顺序与分支推导出来,我们已经实现了顺序,那么接下来只要实现分支即可,而分支有很多类型,如:二选一、N选一、N选M(1

Original: https://www.cnblogs.com/Jcloud/p/16730261.html
Author: 京东云开发者
Title: 轻量级工作流引擎的设计与实现

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/562002/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球