`
ww2
  • 浏览: 401216 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

工作流模式详解之流程控制模式(12、13、14、15)——Multiple Instances

阅读更多

1. 理论模型

  此模型翻译可叫多实例并发模式。其一般的示意图如下:

  

  途中,运行到B 的时候,便生成了 N =3 各工作单元。

  然而这个示意图并不能说明多实例模式的各种细节,具体区分的4种不同的情况。而这里要将这四个模式放在一起论述,是因为我觉得这四种模式一般不会单独使用,很可能是其中的2种之间的契合。

2. 四种多实例

  (12)Multiple Instances without Synchronization
  注意看到这个模式,主要是用于表示实例之间的运行相互"非同步"的状态。按照普遍比较接受的说法是:N个实例之间相互独立而且并发执行,互不干扰。这类似于在程序上的进程/线程概念。

  (13)Multiple Instances with a Priori Design-Time Knowledge
  这一模式是用于确立多实例的入口方式。入口主要处理的问题就是确定所需要生成的实例个数 N 。而这个 N 在设计流程的时候就确定了。

  (14)Multiple Instances with a Priori Run-Time Knowledge
  入口方式也可以动态确定,这一模式是表示在流程运行的过程中,B 中第一个实例产生以前就确定 N 。当然了,确定这个N 的时机可以是前面 A,也可以是 A 前的工作任务。总之是在第一个实例产生前就确定下来的,也可以视作该模式的应用。

  (15)Multiple Instances without a Priori Run-Time Knowledge
  与上面模式相反,是在 B 产生最后一个实例以前(或者所有实例合并以前),都可以产生新的实例,而且不限数量。

3. 一点思考

  从上面四种模式可以看到,四种多实例模式实际上分成了两大部分。我总结为"实例生成"模式和"运行时关系"模式。"实例生成"模式,指明了多实例模式所需要的前提条件(主要是实例个数N),而"运行时关系"模式,则给出了多个实例产生以后的相互关系。所以,多实例模式的应用是通过"实例生成"模式和"运行时关系"模式的结合,才能完整的表示多实例的业务。

  "运行时关系"模式,只有(12)Multiple Instances without Synchronization,其余的则是属于"实例生成"模式。

  一些朋友曾经问,为什么没有 Multiple Instances with Synchronization 模式。在我的观点看来是一个设计重复性的问题。试试来看这个同步的多实例:所谓的同步,即是多个相同的实例轮流运行,从设计的角度来说,这种与顺序方式同构:

  

  这样铺展以后,相信都已经很清楚了,这实际上是一种循环模式,用(4)Exclusive Choice可以实现,如:

  

  可见,如果有 Multiple Instances with Synchronization 这种说法,那实际上只是一种循环而已(循环模式在后面再详细论述)。

4. 各种多实例实现方式的比较

  多实例实现方式之多,恐怕是各种工作流引擎中差异最大的,因为不同的解决方案带来了整体的拓扑结构迥异,也是得这些不同方式所能表示业务的能力相差很大。跟据我所知,大致有如下几种:

  ☆单一个工作单元的多实例
  这是一种最为简单的,即在一个 Active/Task 之中带一个数量参数 N。当这个 Active/Task 初始化的时候就生成 N 个实例,实例之间并发执行。但是有一个难点,就是签收(或者资源模式中Offer的概念中,这个概念类似于待签收状态,在以后讲述工作流资源模式中再详细铺展)中要特别处理,否则可能会出现有多个相同的任务出现在签收列表中而引起混乱。而在一些情况下,更要加一些额外的处理,譬如不能让两个实例给同一个人签收等(这些在工作流资源模式中另有解决方案,但是在流程模式中并没有考虑,我就在这里先提出来)。
  这种方式的优点是对于初级用户较好理解,而且使用较为简单。但是缺点也是很显然的,就是表述业务的能力有限制,无法表示每个实例内有多各流程步骤的情况,而且技术实现上要做特殊处理,尤其是在多实例完成后合并的方式没有给流程的设计者太多的选择余地。

  ☆多实例与子流程的结合
  
这种方式的出现,主要是为了解决上面方式中无法表示多实例内部的流程。其实现主要是利用上面的实现方式,在可生成多个实例的 Active/Task 的内部嵌入了子流程。当进入当中某一个实例中,便启动子流程。同样,这种方式仍然容易在签收的环节引起混乱。
  同样,这种方式对于初级用户来说也很好理解,使用学习也并不复杂。但是流程设计的操作可能较为繁琐,而且并不很直观,对于工作流的高级应用:分析、优化等都是一个较难处理的环节。还有仍然存在上一个实现方式的缺点:多实例的合并方式选择余地不多。

  ☆区块/分组
  
区块/分组的方式,是指限定一些 Active/Task 的子集,方便重用。而有的引擎则更进了一步,让一个区块/分组也引入了数量的概念,如单一工作单元多实例的处理方式一样的可以初始化多个实例。如:
  
  
  一般说,区块/分组要特别处理名字,使其不产生冲突。而多实例的应用,更增加了这个区块名字空间处理的复杂度,所以鉴于技术难度很少引擎会采用这种方式。但是这种方式是把子流程扁平化了,对于最终用户来说也非常直观,而且区块/分组的概念,让一些分析、优化的算法更容易实现与整个流程而不会被子流程所隔断。

  ☆拓扑实现
  
这种方式则更为直接的对应了多实例方式。就是工作单元自身以独立的方式复制副本,其后的执行则形成拓扑结构的分支。这种方式只能在动态生成 Active/Task 的引擎中实现。一般来说,实现一个工作流引擎有两种方式,一种是较为简单的根据流程定义执行任务代码.(这种方式实现简单,一般是针对状态机的。这种实现来说,流程的推进根据定义,只是执行 Active/Task 中的业务代码);另外一种方式则是根据定义生成 Active/Task 实例,再由任务实例执行业务代码。而后一种方式,因为 Active/Task 是独立实例而且动态创建,所以当一个 Active/Task 自己 Clone 了自己以后,两个实例都根据定义找到了自己的后趋 Active/Task,也生成了各自独立的后趋。如:
  
  这里看到,B1 只要 Clone 了自身,便可产生多个分支流程。单这种实现显然设计的时候并不直观,因为设计流程的时候可能是这样子的:
  
  最终用户可能会比较难以理解这个图本身的意义,因此可能在分析设计阶段引起沟通的障碍。但是这种方式好处也是很显然,首先是可以任意扩展多实例中间的步骤,其次是可以任意选择实例的合并方式,在设计上灵活性很较大。

  就我所知道的这几种实现方式来说,也有的是两三种不同方式的组合,再多的方式就限于个人见识了。

5. 应用

  这个模式的应用就十分的广泛了,譬如工程中多个部门的合作、协办、汇签等业务。汇签的例子:

  

  注意我使用这种拓扑实现的方式,其好处是可以随便换去合并方式。若投票选举,N个副总只需要半数通过,就可以通过这个业务,则 AND 的合并方式可以改成 N选M 的模式。若是要求全数通过,则是用 AND 的方式。若是只需要得到其中一个副总的通过,那就用 OR 的方式。这个流程设计就显得很简单了。若不是采用拓扑实现,那业务上如果变更汇签的方式,则要用硬代码实现了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics