1. 流程起点模型
任何事物都有由头有尾,一个流程也不例外,那么现在我们就从流程的“头”——流程起点说起。一个工作流能够运行,就需要一系列条件来激活。而这个激活的位置,就是“起点”(Start Node)。需要说明的是,起点也是一种任务节点(Task Node)。这个特殊的任务节点也许会执行一定的操作,也许仅仅只是一些数据状态的改变。但是,不论什么原因,最终会导致一个流程实例的产生——流程被激活了。
1.1. 单起点
单起点(Single Start Node)估计大家都比较容易理解,现实中工作流应用的也是最为普遍。如下图所示,其就是单起点的模型。
1.2. 多起点
多起点(Multi Start Node )的工作流,在现实应用不是太多。其主要表达的是:在同一流程中,存在多个起点。说到这里,有必要重新申明一下:起点也是一种任务节点,而不是独立于工作流任务特殊节点。多起点的工作流模型,基本上有如下三种方式。
1.2.1. 多起点方式一
起点A 和起点B,它们都可以激活流程的运行,而且激活后,流程都会
共同指向Task A。所以,对于Task B 来说,其不关心流程是如何激活的,其只关系从Task A是否正确的传递来正确的流程数据。如下图:
1.2.2. 多起点方式二
在方式二中,起点A 激活工作流后,导致流程沿着Task A——Task B
——Task C 方向流转。而从起点B 激活工作流后,Task A 则被跳过。这种方式,在现实中是极为少见的。如果将Start B——Task B 这条流程段与Start A——
Task B 这条流程段,分开来看。则可以近似看作的两个“子流程”的选择性汇总(两选一,或多选一)的情况。如下图:
1.2.3. 多起点方式三
方式三(如下图),虽然也存在多个起点,但是基本是按照一个统一流程方向运行的。这是与方式二最大的区别所在。在此,须要再此申明:一个起点(Start Node)同时也是一个任务节点(Task Node)。参看图中的Start B 节点。此种方式,在现实中,还是有一定应用性的。特别是在多个流程之间信息交互的时候,流程A 发送消息数据,激活流程B的运行。但是未必是从流程B 的默认激活点激活,可能是从流程B 的中途某个任务激活。比如图中的Start B 任务节点。
2. 流程激活模型
上面我们看了工作流的起点模型。也知道任何流程,都必须有起点,或者相对的起点。一个流程被激活后,会从起点开始沿着预定的流程路线,有序或无序的往下进行(注意,我这里提到了“无序”二字,我将在后续讲解“无序”状态)。所以,起点就是这个流程被激活的源头。
2.1. 人工激活
大多数的流程激活,都是因为人为的信息数据输入或产生。比如一个订单处理流程,客户提交了订单信息(订单信息数据产生),则激活了订单处理流程的开始。
2.2. 定时或限时激活
在一个特定的时间,因为特定的情况,符合特定的条件,激活某个特定的流程(或任务)。这种激活方式,在现实中很少单独出现,大多数情况,都因为在某一个流程中,因为在限定的时间内,因某项任务未达到预期的状态,而激活另外的任务或新的处理流程。也就说,这种方式,是受外来因素影响的,而且大多与一些流程任务(或流程模式)一起出现。举个定时激活的实例:比如,订单处理流程,限定5 天内发货,那么定义在第三天的时候,如果没有接到发货通知,则激活一个催办信息(催办任务)。这样流程系统,会在第三天的时候自动发出催办信息。
2.3. 外消息激活
这种方式,大多是在多流程信息交互(或大小流程嵌套)应用中。现在比较流行的业务流程整合/管理(BPM),基本上都涉及到这方面内容。如下图所示,流程A,在结束的时候(在以下的所有图中,将采用红色框图,表示结束节点),会向流程B 发送Message,以激活流程B 的运行。至于这个消息是Soap 消息,还是通过消息中间件转发的Message,这就是不同的应用方式了。一般现实应用中,都需要考虑JMS 或WebService 的应用接口。从个人目前所实施过的工作流应用来说,大多还是采用Message Query 方式居多。虽然软件的发展,逐渐SOA(面向服务)化,但是WebService 的安全性或数据正确性,还有待进一步的发展,从这一方面说,比起消息中间件的高度安全性和消息正确性,WebService 目前还是稍逊一筹。其实,安全性和信息正确性,是很多应用客户非常关心的焦点。但是,SOA 化的发展是未来的趋势。所以现在大多的应用都会提供JMS 和WebService接口,或其他类似接口。
上面说了那么多,但是我想很多工作流的文档,都少有提及。什么起点模型,什么激活模型,似乎都是一个陌生的概念。但在现实中,如何去处理好一个流程的起点,特别是存在多个起点情况,是件至关重要的事情。因为流程必须从起点激活(这里的起点可以是开始起点,也可以是中间起点),而且激活的方式又是什么?是人工操作激活,还是Timer,或者外界信息的激活,都有可能。当然,至于如何激活,Timer 如何设置,外界信息如何正确的处理等等问题,就不是本篇的讨论主题。
3. 流程运转模型
3.1. 简单运转模型
3.1.1. 串行
串行(Sequence)是最为简单,也最为容易理解的模型。按照预定的任务列表,有序的执行,如下图所示。
3.1.2. 自循环
自循环(Self-Cycle)的模型,主要用于表示:同一个任务节点,重复的执行多次。
如图中所显示。“模式2”比“模式1”多了一个鉴别节点(Discriminator Node)。这两种模式,在现实中应用的都较为广泛,其中“模式1”更多的偏向人为的选择,也就是说,在任务执行后,由人为的决定是否继续重复的执行这次任务;而“模式2”则更多的倾向于一个既定的规则,按照原有的规则,决定是否重复执行。举例子:在电子政务办公系统中,经常出现的“多处长联合审批”过程。多个处长(个人)属于同一个处长角色(角色单元)。针对同一个审批过程,采用自循环(审批这个过程重复执行)就可以基本解决问题。
3.2. 发散运转模型
3.2.1. 并行
并行(Parallel),在有的某型中叫“And 模式”。是说在流程运行过程中,因为不同的条件或情况,或者处理的业务需要多部门(多任务)分开处理,而产生了流程分支。如下图所示。
流程在执行完任务A 后,因为需要,产生了两个并发执行的分支(A——B 和A——C)。这两个分支之间是对等的,也是并行执行的。还有下面类似的图形。
虽然比上图多了一个And 选择器,但实际上,两图,表示的是同一个含义或模型。
3.2.2. 异或模型(显式)
异或(XOR)显式模型,又叫Exclusive Choice(独占式选择)当一个任务处理完后,发现其后面可允许走多个分支流程,但只允许选择其中某一个分支运行。如下图所示,虽然在任务Task A 后预订了三个不同的任务,但是仅Task D 满足条件(一般多为人工操作选择),造成后续的流程中,走了A——D 分支,而另外的分支被抛弃。
3.2.3. 异或模型(隐式)
同为XOR 模型,隐式和显式的区别不是太大。唯一的不同点就是,隐式XOR 模型存在多种可选择的分支,但最终,依然仅有一个分支运行。如下图所示,存在分支A—C 和分支A—D 都满足条件,但最终也依然只能有一个分支被激活。至于哪一个分支被激活,这可能是人为的操作,也可能是某种随即的自动选择。不论哪种方式,人须保证一个分支被激活后,其它分支被抛弃。
现实中,隐式XOR 模型的应用非常少,而且大多数的工作流引擎不支持这种模型,仅支持显式XOR 模型。在XPDL 中的XOR 模型中,并没有提出“显式”和“隐式”的概念,默认还是以显式XOR 模型为操作方式。
3.2.4. 鉴别模型
鉴别模型,在标准的Workflow Patterns 表述中,又叫Discriminator Choice。
这同前面的“独占式选择”很相似,唯一不同点,就是多了一个鉴别器(Discriminator)。当任务达到这个鉴别器的时候,鉴别器会根据当前流程所处的状态,对比预先设定的一些选择规则,自动判别接下来流程的流向,也就是自动根据条件,选择一个满足条件的分支运行。
鉴别器模式(有的可能叫选择器等等名字,表达的意思基本相同),在现实应用中较为广泛。比如在订单申请流程中,设定一个依据数额判别流向的鉴别器,如果数额大于等于5000就走分支流程B,如果数额小于5000 就走分支流程C。
3.2.5. 抄送模型
抄送模型,本身不是一个标准的工作流运转模型,但是在现实应用中,比比皆是。它表达的意思是(请参考下图),存在主流程(A——C),在一个任务(A)执行完毕后,会继续执行主流程上下一个预定任务(C),但是同时也会激活另一任务(B)(或另外的流程)的执行,但是任务B 以及任务B 的后续流程,不会对主流程运转造成影响。请注意图中的A——B 流程沿线,用的是灰色虚线表示,而且任务B 也同样采用灰色表示。
来个举个电子办公系统中,经常遇到得例子说明一下:比如一个发文,在交司局会签的时候,可能会抄送一份给另外的司局备案,这个过程就或额外的激活一个不影响主会签流程的“抄送任务”,比如图中Task B。
3.2.6. 发散模型
说到这里,大家可再回过头参看一下并行模型(3.2.1 节)。发散和并行最大的区别就是,各个分支(branch)的流程状态(或流程数据),在并行模型中,分支状态(A-B)与分支状态(A-C)是大多数情况下是不相等的。由任务A 执行后的状态进行一定条件下的“拆分”,形成了两个分支(或多个分支)流程。这多个分支流程,在最终需要重新聚合成一个主流程,以确保流程信息的完整性(当然,实际运行中,可能存在因为超时等特定原因而最终抛弃某个子流程)。而在发散模型中,分支状态(A-B)与分支状态(A-C)是绝对相等的。因发散而产生的多个分支流程,在最终未必聚合(可能因为种种原因,聚合的时候会抛弃一个和多个分支流程)。
3.3. 聚合运转模型
因为有了“发散”,在一个流程的后续运转中,才会出现“聚合”这个问题。所以在后续讨论聚合模型的时候,大多情况下都会结合上面的发散运转模型。
3.3.1. 同步聚合
有必要说明一下,同步聚合(Synchronize merge),可不是“同时聚合”。
同步聚合表示的是:在聚合点,会等待所有分支的到来,如果不考虑超时(一般流程回设定任务执行期限)和异常等情况下,流程必须等待所有的分支(Task B 和Task C)都执行完(到达And 汇聚点)后,才能激活后续的任务,也就说流程才能正确的往下运行。
这里面会涉及到如何聚合的问题,是人工聚合,还是自动聚合。一般这里会引入规则引擎(Rule Engine)来负责分支的聚合,按照预定的规则,将流程数据(状态)汇聚。当然,现实中,分支聚合(或者分支发散)还会涉及到类似“触发器(trigger)”,“定时器(Timer)”,或者各式各样的“监听器(listener)”等等。这些在真正模型应用实施的中必须详细设计,考虑完善。这些内容超出了本文的范围,但大家在实际中需要多加关心。
3.3.2. 简单聚合
简单聚合(Simple Merge)模型,大多的模型文章都采用“异或聚合(XOR Merge)”这个名称。虽然名为简单聚合,不过在现实应用中,其实并不简单。这种聚合一般采用“多选一”的原则,或采用类似“先进先出”法则(人工干预除外)。
在聚合的时候也有可能涉及到流程数据(状态)校验等问题。不够,如够涉及到过于复杂的筛选规则或数据校验规则,似乎采用下面的“鉴别聚合”更好。
当然,一旦某一个分支被通过。则余下的分支则被终止,或者运行到聚合点就结束。
3.3.3. 多重聚合
多重聚合(Multiple Merge),与上面的简单聚合有些相似。但是比起Simple Merge 可就复杂多了。到目前为止,在现实中,很少碰到过这样的流程实施。多分支在聚合的时候,采用类似于“先进先出”法则,但是不同于简单聚合的是,任何一个分支,在到达这个聚会点的时候,均会激活后续流程的运转。(这种情况,是参考WorkflowPatterns 写的,既然存在,想必现实中也有应用。但是后续流程被多次激活,就需要解决这些产生的多实例问题,就将问题过于复杂化。很多工作流产品不支持这种模型,也是比较明智的)
还会涉及到一个问题:如果一个后续流程实例刚刚被激活(还没有运行完),又一个分支到达,那么这个分支是否激活后续流程实例呢?在不同的工作流引擎中(workflow enginner)中会有不同的解决方案,有的选择立即激活,有的选择等待延迟激活。就这一点来说,不是本文的讨论主题,有兴趣的朋友,可以在自己的引擎中实现不同的方式。
3.3.4. 鉴别聚合
鉴别聚合(Discriminator Merge)较容易理解,应用的也较为广泛。一般情况下,流程中不大会独立存在。通常会结合“同步聚合”或“简单聚合”之类的存在。鉴别的目的,就是更准确的聚合,让那些符合特定条件的分支聚合。
但在现实应用中,考虑的就比较多。在“同步聚合”中,需要负载一些辅助性功能模块。通常都会存在一个“规则引擎”,来定义或处理聚合规则
3.3.5. 优先聚合
有关优先聚合,赋予一定的优先级别。打破通常的“先进先出”的规则。
3.4. 特殊运转模型
既然是特殊,当然是普通流程模型中所少见的。在Workflow Patterns 中,以下的几种模型似乎都没有被提及过,也许老外的流程应用较为规矩。以前我是从事电子政务流程开发的,下面的几种模型,在电子政务的工作流应用中,较为普遍。说出来,也算参考一下。虽然标准没有提及,但并不代表应用没有。Wfmc 的xpdl
标准更多的是基于工业化流程处理,偏向自动化处理事务,所以人为的参与就比较少。但是国内目前的工作流应用,大多就基于人的参与,所以人为的操作(包括权限)就很重要。
3.4.1. 回退
回退,在有的应用中叫“退回”。如下图所示,有任务A 到任务B 属于正常发送,但从任务B 到任务A,则出现两种情况:(1)正常发送,如图中B—A 蓝色线;(2)可能因为某些特殊原因,被任务B 退回,要求任务A 重新办理,如图中B—A 红色线。虽然都是从B 到A,代表的意义却完全不同。
这种应用,在现实中应用比较多,特别是电子政务中的公文流转或审批。
3.4.2. 自由流
自由流,表示的是一个任务执行完后,但其后续的运转不按照预定的顺序进行。而是人为地动态选择。
如上图所示,原先的是流程是按照A—B—C 顺序执行了。但是执行任务A 之后,人为地让流程沿A—C 方向运转,直接跳过了原先的任务B。流程的打乱,会造成很多问题:数据的完整性,流程的可控性等等,这些问题都会随之而来。所以很多工作流产品并不支持自由流的存在。不过这一现象在电子政务系统中,较为普遍。在工业化流程中,可能就较为规范,出现的可能性较低。
3.4.3. 委托代办
委托代办,从理论上说,不能算是一种模型。确切的说,应该是应用中一个需要处理的问题。由于在现实应用中,较为普遍的存在。就在这里顺便简要的提一下。一个任务交给了员工A(角色A)处理,但是员工A 最近出差,无法正常办理,就可以委托给员工B(可能是角色A,也可能是角色B )处理,以保证流程能够正常的进行下去。
3.4.4. 催办
催办,和上面的“委托代办”,以及下面即将介绍的“取回”,都属于应用中,需要解决一类问题:在执行完任务A 到任务B 的运转后,任务A 设定一个催办日期,在催办日期到来的时候,向任务B 发送催办请求,以催促任务B 的执行。其前提是,任务A 已经执行过,任务正在执行(有可能已经执行完)。
3.4.5. 取回
取回,在流程中也是较为通用的动作:流程由任务A 运转到任务B,任务B 虽然接受了A所发送的请求或数据,但还没有确认执行的情况下,任务A 有权取回,重新执行。举例:科员起草了一份文件,交给处长审批。但处长还没有察看的情况,科员有权取回文件,重新修改。
4. 流程组合嵌套模型
一直到现在,所说的模型,都是定位在“任务之间的关系”。不论前面的发散运转模型,还是聚合运转模型,都只是流程内部的任务关系,而不涉及到流程与流程之间的关系。请参看下图,虽然任务很复杂,但是所有的任务都限定在同一个流程中,而且为了巩固前面的一些运转模型概念,特意在里面包含了并行,发散,自循环,鉴别聚合,同步聚合等模型。
让我们再来看看下面的流程,看起来比上面的流程简单,其实不是。仔细的看,其实这里面有两个流程在运行,一个主流程内嵌一个子流程。
接下来,就来看看流程与流程之间会存在什么样的关系,存在什么可能的模型。
4.1. 内嵌模型
内嵌模型刚刚已经提到了,就是在一个主流程中,内嵌了一个或多个子流程。每个子流程自身可能是可独立运转的;也有可能是主流程的辅助性子流程,不可独立运行。
4.1.1. 主流程等待方式
请参考下图,在主流程运行到“Router”位置的时候,会激活一个子流程的运行;在子流程运行完后,会重新运行到主流程的“Router”位置,继续主流程的运行。
在这种方式下,当子流程运行的时候,主流程会暂停,等待子流程的完结。
4.1.2. 主流程也运行方式
比较下面的图与“主流程等待方式”的图,就会发现很大的不同。与“主流程”相同的是,当主流程运行到“Router”位置的时候,会激活一个子流程的运行。但是,激活子流程后,主流程并没有停止,而是基于按照预定的流程方向运行;同时,激活后的子流程也同样处于软转状态。说到这里,估计很多让都会询问,那么子流程的信息什么时候返回呢?虽然在下图中,表示为子流程的信息返回到主流程的“任务A3”。但是,依然涉及到很多问题,比如:什么时候聚合,怎么聚合的问题了;而且主流程和子流程的运行时间未必搭配恰当,有可能存在主流程首先运行到Task A3 点,而这时候子流程还没有运行结束情况,反之亦然。这种情况,大多数采用“同步聚合”的方式:如果有一方未到达的情况下,另一方会等待。当然,这其中可能涉及到等待超时等不良因素,这时候主流程时选择继续等待,还是发催办消息,还是继续运行,就是工作流引擎的设计问题了。
4.2. 外嵌模型
与内嵌模型不同的地方,就是外嵌的子流程,不返回主流程。在主流程激活子流程后,主流程继续运行,且不关心子流程的运行状态或运行结果。参考下图,你会发现其与内嵌模型中的“主流程也运行方式”非常的相似,区别就是,子流程最终没有返回到主流程。
5. 流程整合模型
流程整合的模型,已经超越了“流程运转模型”的概念范畴。但是作为目前“系统整合”的一个比较流行的趋势,拿到这里顺便提一下。现在的业务越来越复杂,跨区域,跨部门之间信息交互方式的需要越来越明显,而且跨区域,跨部门之间业务配合也越来越多。从信息整合的发展来看,“面向应用的数据层整合”和“面向服务的接口层整合”都逐渐走向“BMP”模式:由中央主流程控制多个子流程(分布在不同地域或不同部门,各自独立的流程)协同运行,以达到整个业务逻辑的运行。
其实在第四章“流程的激活模型”的“外界消息激活”模型中,我已经简单提到了一些,只是不太明确。那么现在让我们来看看一个普通的“流程整合”大概是什么样子的,请参看下图。实际的整合要比这张图上的复杂很多,也许还会有一些JMS/WebService 等的信息交换接口,可能用到不同厂家的数据交换平台,或消息中间件等等;当然那些安全措施也必不可少了。简单的整合模型,基本上都是采用“主流程控制”的方式:由一个主流程控制整个流程的运行,由各个子流程具体完成某项任务,并向主流程返回处理结果。主流程在确定子流程正确运行/处理完后,并得到处理完的信息后,会继续按照预定的流程路线,激活另一个子流程。在有的流程整合设计中,主流程本身不完成任何任务(只负责运转控制);而有的设计中,主流程本身自己也需要完成一些任务。
6. 流程终止模型
6.1. 按分布分
主要是从节点的数量和形态上分析。
6.1.1. 单结束点
表明流程仅允许一个“结束点”存在。
6.1.2. 多结束点
表明流程许多个“结束点”存在。
6.1.3. 非标准结束点
既然是一个非标准结束节点,就是说流程结束的地方,不是原先定义的流程节点。有可能在流程中间因为异常,或人为的强制终止。
6.2. 按行为分
从行为上来看,流程的结束,基本上存在下面的三种情况:“正常”“异常”“激活新任务”。
6.2.1. 正常终止
按照预定的流程运转,到达结束节点后正常结束。当然上面说到的“人为强制终止”也应该算是一种正常情况。
6.2.2. 异常终止
因为非正常因素,系统在运行过程中产生严重的异常,造成流程非正常终止。一般针对这种可能存在的情况,流程引擎都会制定一整套处理机制,而且系统监控模块也需要报告异常的来源和起因。