(序):模式是个什么东东?伟大的Alexander大师
“道可道,非常道;名可名,非常名。”这是我们老祖宗老子《道德经》中开篇的两句话,意思是:可以用语言描述的道,不是真正的道;可以用名字来命名的道,这个名字也不能形容妥当。其终极思想是,由于人的认识的局限性,我们所说的道,都只是真正道的一部分,无法窥见道的全貌。当然老子后来又在《清静经》中说:“吾不知其名,强名曰‘道’”。也就是说:“这个‘道’字虽然不肖,但我(老子)还是先把这个终极真理叫作‘道’好了。”
“道”,可作道理、途径、真理、方向、方法等解释。按照老子的说法,世界万物都有其本质和终极真理,但是“吾不知其名,强名曰‘道’”。在现代,人们已经把“道”作为事物的本质了。
C.亚历山大[1]在其著作《建筑的永恒之道》一书中说:“建筑或城市只有踏上了永恒之道,才会生机勃勃。”亚历山大在书中描述了253个建筑模式,并首次提出了“模式语言”一说,算是“模式语言说”的开山鼻祖了。他曾领衔撰写了5卷关于建筑设计的丛书[2],其中前两本《建筑的永恒之道》和《建筑模式语言》最为知名。
很多的技术人员和非技术人员都听过模式,例如管理模式、思维模式、商业模式、建筑模式、设计模式等等,对它有着无限的迷恋。很多行业与领域里也都有模式一说。在软件领域,大名鼎鼎的面向对象的23种设计模式更是无人不知,无人不晓。那么,到底什么是模式呢?
模式(pattern)是解决某一类问题的方法论。把解决某类问题的方法总结归纳到理论高度,就是模式。它是一种指导,是一种解决某类问题的最佳实践。借助于模式,我们可以利用前人的经验和智慧,做出优良的设计方案,达到事半功倍的效果。模式语言则是模式对应于那些使建筑美妙的深刻观察的模式集合,是对如何建造的认识的总和。建筑的永恒之道正在于建筑模式,在于我们对建筑的认知达到一致,即拥有共同的模式语言。
一点题外话:
按照《建筑的永恒之道》的说法,在古代,农民都是自己造房子,他们自己都有模式的直觉;在工业化时代,人们以为自己不能设计,必须倚靠设计师,而设计师也耽迷于流行的模式而设计出没有活力的东西。所以我们缺少的是模式之道,或者说不知道怎样鉴别什么是有“活力”的模式。如今的软件领域何尝不是如此?我们就见过很多牛逼哄哄、所谓的架构师和设计师,他们讲起模式来一套一套的,但是设计出的软件架构奇烂无比,有的甚至不会将架构转换为框架,实在是比古代的农民差远了。我们认为,做软件的同仁们,如果你想真正地成为一个优秀的架构师或设计师,《建筑的永恒之道》这本书是必读的。它告诉了你什么是道,模式之道。这个道才是灵魂,才是核心。这个道是使之“有活力”,而不是生搬硬套。如果有时间再读读第二本《建筑模式语言》。最后还有个小提醒,优秀的架构师、设计师不是读了几本大师的著作就能成就的,他们也是在
“理论—实践—总结—再理论—再实践—再总结”这样的长时间循环中磨练出来的,而且我们认为这个时间至少要7-8年以上。
在《建筑模式语言》一书中,C. 亚历山大将模式分为三个部分:
首先是此类问题所在的上下文(Context),即当前模式所面对问题的周围环境和状况,也就是说,模式在什么状况下发生作用;
其次是动机(Motivation),即此模式的目的或预期的目标是什么;
最后是解决方案(Solution),即为达到预期目标或解决此类问题所采用解决方案的核心。
通过上述描述,我们可以得出结论,模式实质上就是从不断重复出现的事件中发现和抽象出的规律,是解决问题所形成经验的高度归纳总结。只要是一再重复出现的事物,就可能存在某种模式。而当一个领域逐渐成熟时,自然而然就会出现这个领域的模式。借助亚历山大的模式理论,GOF在软件领域提出了23种设计模式。同样,在流程领域也自然而然地出现了“工作流模式”。
本书的名字《流程的永恒之道》套用了亚历山大的经典名言:“流程只有踏上了永恒之道,才会生机勃勃。”那么流程的永恒之道是什么呢?在本书中,我们将会依次为读者讲解三个永恒之道。本章首先讲述第一个永恒之道,即流程万变的永恒之道——工作流模式。
工作流模式作为流程的灵魂,是时间无关的(timeless),它与人、文化相关,不会随着时间和新技术的发展而落后,因此可以称之为永恒的。道德经又曰:“道生一,一生二,二生三,三生万物。”把这句话套用在工作流模式上非常准确,工作流模式可以生一,生二,……,最后生万物,演化出无数个不同模式组成的流程。可以说,没有工作流模式就没有流程,工作流模式是流程万变的永恒之道。接下来,我们就围绕工作流模式展开,看看流程万变的永恒之道——工作流模式是怎样来生一、生万物的。
工作流模式的发展历程及分类
在上一节,我们了解了模式,根据模式的通用定义,我们在此给出工作流模式的定义:工作流模式是解决流程类问题的方法论,是解决流程问题的最佳实践。工作流领域同样存在着大量的不断重复出现的事件,从这些事件中发现和抽象出规律,并找到解决这些重复问题的解决方案,对这些问题及其解决方案进行归纳总结,就形成了各种各样的工作流模式。
1999年,由荷兰埃因霍温大学的Wil van der Aalst教授[3]与昆士兰大学的Arthur
ter Hofstede教授联合创立了Workflow Patterns Initiative,并提出了工作流模式的概念。他们的研究报告于2000年在以色列埃拉特举行的CoopIS大会上正式发布[4]。
两位教授一共总结了 21 种工作流模式[5](其实是指21种控制模式)。2004年,Nick Russell教授加入了Workflow
Patterns Initiative,并扩展提出了工作流数据模式和资源模式。2005年扩展出了异常模式,2006年工作流控制模式被扩展到了43种模式[6]。经过这样的发展,工作流模式被分为了控制模式、资源模式、数据模式、异常模式四大类。
接下来,我们以2000年初江南市房管局的“实现房改购房审批流程的自动化,并可以灵活变化”这个业务需求为例,描述工作流模式在具体应用中的实现过程。图3.1给出了房改购房审批流程的组成结构。
图1 房改购房审批流程
从图中可以看出,整个房改购房审批流程由“受理”、“初审”、“公告”、“复审”、“查封核查”、“制证”、“收费”、“发证”等多个环节组成。该流程有明确的作战目标,就是给购房改房的申请人发放“购房证”,其中的每个环节都可以看作是一个作战活动。
这些作战活动的组成是有一定规则的,例如串行、分支、并发等规则,这些规则还有可能经常变化。对于这些规则,在工作流技术中是由“控制模式”来负责的。控制模式负责控制作战活动的组成与流转。
(一):控制模式之串行、并发分裂及并发汇聚模式
控制模式是流程的中枢神经,它在作战小分队中负责将多个单独的作战活动组合在一起,并推动活动的自动化流转,形成作战流程。其重要性不言而喻,因此要设计一个好的流程,就必须学会应用各种各样的控制模式。
在探寻每个模式的究竟之前,我们首先定义一个统一的格式,对于控制模式,将按照如下统一的格式进行描述:
模式描述
我们在探寻每个控制模式时,将按照如下统一的格式进行描述。
1.原型实例(故事片段)
给出此模式的故事片段,通过鲜活的工作流故事展现此模式的应用场景。
2.上下文(描述、动机)
给出此模式的具体描述和动机:为什么有此模式,是为了解决什么问题。
3.问题的本质
此模式的本质是什么?即本质上要做什么事情?
4.解决方案及技术实现
给出此模式的解决方案及技术实现。
5.约束及可能存在的问题
此模式可能存在的约束和问题。模式并不是万能的,在软件中没有银弹,同样也没有包治百病的模式,每种模式都有可能存在一些约束及限制条件。应用此模式可能会引发什么问题,怎样解决这些问题。
6.规范中的实现
给出此模式在相关规范中的实现。目前流程有三大规范XPDL、BPEL、BPMN,我们将按照每个规范的最新版本XPDL
2.1(需要说明的是,本章中的XPDL示例,都是由BizAgi Process Modeler 2.1.0.1生成的)和BPMN
2.0(所有BPMN 2.0的XML定义,都是由signavio提供的在线流程建模器生成的),来描述当前模式在其中的实现。对于BPEL,我们始终认为它不是一个“流程”语言,其本质上是一个Web服务的编制语言,因此只有部分模式使用BPEL描述。
7.与其他模式的关系
此模式与其他模式有什么样的关系?是否有配对使用的要求?是否有与其他模式进行组合,解决复杂场景的情形?
1.1.1 房改购房审批流程中的串行模式
图3.2是江南市房管局房改购房立等可取的审批流程。在这个流程中,所有的作战活动都是串行在一起的,完成一个活动才能操作下一个活动,这就是工作流控制模式中的“串行模式”。串行模式极其简单,这里就不按照统一格式进行描述了。
图3.2 房改购房立等可取的审批流程
1.1.2 房改购房审批流程中的“并发分裂“与”并发汇聚“模式
1. 并发分裂模式
1.原型实例(故事片段)
图3.3 房改购房审批流程的“并发分裂”原型实例
如图3.3所示,复杂的房改购房流程需要两个核查岗位进行核查,因此在“复审”环节之后,并发分裂为了两个活动:“查封核查一”与“查封核查二”。在这个故事片段中,为了提高效率,两个核查环节并行工作,从而将核查的时间缩短了一半。
2.上下文(描述、动机)
描述:并发分裂,就是在某个活动(本例是“复审”)之后,并发地分裂出多个活动(“查封核查一”、“查封核查二”),这多个活动同时执行。
动机:通过增加流程中并行处理的活动的个数,缩短串行时间,提高整个流程的效率。在1.2.2节中,我们曾经提到过并行工程,并发模式是一种最有效的提高流程效率的模式。
3.问题的本质
并发分裂模式的动机是尽量增加流程中可以并行处理的活动的个数,从而极大提高流程的效率。那么,怎样才能提高并行活动的数量呢?或者说,并行活动的增加依赖于什么呢?答案就是资源,即执行活动本身所需要的相关资源(3.4节会重点讲述这一主题)。资源如果不够用就没法并行,在房改购房审批流程中,如果只有一个核查岗位当然就无法并行了,因为一个岗位不能同时做两件事情。本例设置了两个查封核查的岗位,因此可以设置为并行活动。
因此,活动能不能并行处理,就要看这个活动本身的相关资源能否并行。再如,在非计算机化的人工流程中,如请假流程,如果请假人拿一张纸质的请假单去找领导签字,那么他只能按照串行顺序去找所有的领导签字,因为物理存在的纸只有一张。而计算机的一个很大作用就是把纸质的数据电子化了,电子化的本质是电子数据本身可以被同步处理,这就是说在同一个电子请假单上,多位领导可以同时签字。因此,原来由于资源的限制而不能并行处理的活动,在计算机化之后可以并行处理了。
4.解决方案及技术实现
解决方案。要实现并发分裂模式,可以在要并发的活动之后添加一个标识并发分裂的路由节点,如图3.4中的AndSplit,被称为显式的实现方案。或者省略路由节点,直接在活动之后连接两路并发的活动(参见图3.5),被称为隐式的实现方案。
图3.4 并发分裂模式之显式实现方案
图3.5 并发分裂模式之隐式实现方案
技术实现。在工作流中实现并发分裂模式,技术实现包括两部分:一部分是在流程定义期,一部分是在流程运行期。
(1) 定义期。通过可视化的流程设计器,采用此模式的两种方案中的任意一种,画出流程定义图,并持久化存储到数据库。持久化存储的流程定义,在运行期又逆向解析为多个工作流对象之间的关系,如图3.6和图3.7所示的结构。
图3.6 活动与转移的类图
(2) 运行期。流程引擎需要读取持久化存储的流程定义(一般为XML格式),并解析为对象及对象集合之间的关系(活动集合Activities、转移集合Transitions),如图3-7所示。
图3.7 并发分裂模式中隐式方案的对象关系图
可以看出,这是没有采用AndSplit网关的隐式实现方案:
(1) 将XML的流程定义解析为对象之间的关系,本质上就是ActivityInfo与inComingTransitions、outgoingTransitions的关系。inComingTransitions集合存储进入当前活动的转移线对象,outgoingTransitions集合存储离开当前活动的转移线对象。当某个活动实例(例如“活动A”的实例)完成需要转出时,则首先取得“活动A”这个ActivityInfo对象的outgoingTransitions集合并进行迭代,并对每个transitionInfo对象上的condition表达式(用来判断当前转移要执行的条件)进行求值判断,如果判断结果为true,则执行此转移。
(2) 对于并发分裂模式,如果其转移线上的条件表达式condition不设置,即永远默认为true,那么在并发分裂模式中,其所有的后继转移线(outgoingTransitions集合)都将被执行,从而实现并发分裂模式。
(3) 每个outgoingTransition对象(TransitionInfo)执行完毕后,则根据TransitionInfo对象的toActivityId属性取得此ID对应的活动对象(ActivityInfo),在本模式中即“活动B”与“活动C”两个对象,在每次迭代中,对ActivityInfo对象进行实例化,并持久存储,即完成了一次迭代。所有迭代执行完毕,即实现了“活动A”并发分裂为“活动B”与“活动C”的运行期功能。
注:后续所有控制模式的运行期实现,都将遵循outgoingTransitons、incomingTransitions、fromActivityId、toActivityId、condition这样的机制,因此在后续的控制模式中,不再单独讲述这一部分内容了。
对于更细层次的编码实现,目前有基于petri网的Token机制(例如jBPM),也有基于实例的状态机方式。
5.约束及可能存在的问题
驳回的问题。在本模式的描述、解决方案及实现中,我们可以看到并发分裂模式的AndSplit网关之后分裂出的所有分支都是同时执行的,因此如果驳回到AndSplit网关之前的活动(例如由“活动B”驳回到“活动A”,而“活动C”并不驳回),再次执行到AndSplit网关时,“活动B”重新执行了一次,而“活动C”也会再次被执行,但是“活动C”并没有被驳回,它还需要不需要被再次执行呢?在并发分裂模式中,“活动C”必须再次被执行。但是这可能不是业务所期望的结果(业务上可能会要求“活动C”不要再重复执行了),遗憾的是并发分裂模式解决不了这个问题。目前很多的工作流产品,虽然支持并发分裂模式,但是对于并发分裂的驳回只能做到“活动B”与“活动C”全部重复执行。如果要支持可控制“活动C”是否重复执行,只能引入多选分裂模式与多选汇聚模式两者结合来实现(详见10.3.2.2节的的多选分裂模式与10.3.2.3节的多选汇聚模式)。
6.规范中的实现
XPDL 2.1的实现(此XML内容由BizAgi Process Modeler直接导出,去掉了与控制模式无关的属性)
<WorkflowProcess Id="4df39a5e-9a54-490c-aca7-7cf45bf53ef0" Name="Process 1"> <Activities> <Activity Id="a2dca2db-f0ab-4c1d-92c4-2f51d356f51e" Name="活动A"> <Description /> <Implementation> <Task /> </Implementation> </Activity> <Activity Id="67e100a6-f17c-4fb9-80da-c987d918c747" Name="并发分裂网关"> <Description /> <Route GatewayType="AND" /> </Activity> <Activity Id="76f2bf26-f953-40b1-800b-25af4320dbd4" Name="活动B"> <Description /> <Implementation> <Task /> </Implementation> </Activity> <Activity Id="ba088ccb-d74f-409b-8d6c-08c7cf577f70" Name="活动C"> <Description /> <Implementation> <Task /> </Implementation> </Activity> </Activities> <Transitions> <Transition Id="344afd1f-90d9-4d4a-97a2-9b6d909b8601" From="a2dca2db-f0ab-4c1d-92c4-2f51d356f51e"
To="67e100a6-f17c-4fb9-80da-c987d918c747" Name=""> <Condition /> </Transition> <Transition Id="b0b4d8d6-c86d-4262-afda-c6e03925c1d7" From="67e100a6-f17c-4fb9-80da-c987d918c747"
To="76f2bf26-f953-40b1-800b-25af4320dbd4" Name=""> <Condition /> </Transition> <Transition Id="ed12d3a8-7ff4-4cd0-a19c-6eb89fbe5a56" From="67e100a6-f17c-4fb9-80da-c987d918c747"
To="ba088ccb-d74f-409b-8d6c-08c7cf577f70" Name=""> <Condition /> </Transition> </Transitions> <ExtendedAttributes /> </WorkflowProcess> |
如上所示,XPDL规范采用的显式方案(参见图3.4)来实现并发分裂模式。通过并发分裂网关(<Activity
Id="67e100a6-f17c-4fb9-80da-c987d918c747"
Name="并发分裂网关">)与转移(Transition Id="
b0b4d8d6-c86d-4262-afda-c6e03925c1d7"、Transition
Id=" ed12d3a8-7ff4-4cd0-a19c-6eb89fbe5a56")直接建立关系,实现并发分裂网关与分裂转移线的关联。再通过转移线上的From与To属性(见粗体部分),分别指向某个活动Id,实现了线与活动的连接。
BPEL中的实现(XML内容由Eclipse BPEL Designer 生成,去掉了与控制模式无关的属性)
在BPEL规范中,通过<flow>活动提供并发分裂模式的实现。把需要并发执行的活动放置在<flow>…</flow>标签之内。
<bpel:process name="ParallelPattern" targetNamespace="http://sample.bpel.org/bpel/sample" suppressJoinFailure="yes" xmlns:tns="http://sample.bpel.org/bpel/sample" xmlns:bpel="http://docs.oasis-open.org/wsbpel/2.0/process/executable" > <bpel:sequence name="main"> <bpel:empty name="Empty"></bpel:empty> <bpel:flow name="Flow"> <bpel:invoke name="Invoke1"></bpel:invoke> <bpel:invoke name="Invoke2"></bpel:invoke> </bpel:flow> <bpel:invoke name="Invoke"></bpel:invoke> </bpel:sequence> </bpel:process> |
BPMN 2.0中的实现(XML内容由Signavio Process Editor导出,去掉了与控制模式无关的属性)
<process id="sid-a0718229-83f5-4ab3-9fea-63676de90575" isExecutable="false"> <task completionQuantity="1"
id="sid-81CDFBD9-1D50-42CF-B67A-674591D44F4D" isForCompensation="false" name="活动A" startQuantity="1"> <outgoing>sid-FE93BF67-3DE5-4DF9-BAA7-A7F4BD8C3339</outgoing> </task> <parallelGateway gatewayDirection="Diverging"
id="sid-681399DD-E962-4174-85DA-43384A9B0DD8" name="并发分裂网关"> <incoming>sid-FE93BF67-3DE5-4DF9-BAA7-A7F4BD8C3339</incoming> <outgoing>sid-91DD542C-DBA5-49E0-9E56-A31DA8E4E432</outgoing> <outgoing>sid-9DEA8CF3-6EBE-4EB5-B649-42865D58C35D</outgoing> </parallelGateway> <task completionQuantity="1"
id="sid-9FCD307D-BDED-404F-988B-100311E9C92A" isForCompensation="false" name="活动B" startQuantity="1"> <incoming>sid-91DD542C-DBA5-49E0-9E56-A31DA8E4E432</incoming> </task> <task completionQuantity="1"
id="sid-65D2670A-F5CF-4721-854B-F1499C0F3239" isForCompensation="false" name="活动C" startQuantity="1"> <incoming>sid-9DEA8CF3-6EBE-4EB5-B649-42865D58C35D</incoming> </task> <sequenceFlow id="sid-FE93BF67-3DE5-4DF9-BAA7-A7F4BD8C3339"
name="" sourceRef="sid-81CDFBD9-1D50-42CF-B67A-674591D44F4D"
targetRef="sid-681399DD-E962-4174-85DA-43384A9B0DD8"/> <sequenceFlow id="sid-91DD542C-DBA5-49E0-9E56-A31DA8E4E432"
name="" sourceRef="sid-681399DD-E962-4174-85DA-43384A9B0DD8"
targetRef="sid-9FCD307D-BDED-404F-988B-100311E9C92A"/> <sequenceFlow id="sid-9DEA8CF3-6EBE-4EB5-B649-42865D58C35D"
name="" sourceRef="sid-681399DD-E962-4174-85DA-43384A9B0DD8"
targetRef="sid-65D2670A-F5CF-4721-854B-F1499C0F3239"/> </process> |
如上所示,BPMN2.0规范同样采用了显式的实现方案。需要注意的是,在XPDL 2.1规范中,通过在Transition的From与To属性实现了线对活动的连接,而在BPMN
2.0规范中,则是通过sequenceFlow的sourceRef与targetRef属性(见粗体部分)实现线对活动的连接。
7.与其他模式的关系
(1) 与会签模式的区别。此处需要注意的是,活动B和活动C是两个不同的活动(也就是说两个活动做不同的事情,例如在办公用品采购预算审批的流程中,活动A为总经理审批,审批通过后,活动B为通知采购员领款,活动C为从财务系统中扣款),因此要区别于同一个活动有两个办理人同时办理(即单步会签)的情况。
(2) 与并发汇聚模式(同步模式)的关系。并发分裂之后,一般都会在某个活动上进行汇聚。此时就需要用到“并发汇聚模式”。一般情况下,并发分裂模式与并发汇聚模式都是成对出现。当然这并不是必须的,因为并发分裂也可以不进行汇聚,例如传阅模式(异步多实例模式)。
(3) 与单选分裂(排他选择)模式组合使用,间接实现多选分裂模式
图3.8 并发分裂模式与单选分裂(排他选择)模式的结合使用
从图3.8中可以看出,通过将并发分裂模式与排他选择模式相结合,可以部分地实现M选N分裂模式。图中实现的效果是,A分裂为BCD或BCE。在一定程度上实现了4选3的效果。当然活动B和活动C是必选的,活动D和活动E则是排他选择(即二选一)。所以,这与多选分裂又有一定的区别,在多选分裂模式中,选择结果可以是任意一个分支,并没有任何限制。
2.并发汇聚模式(同步模式)
1.原型实例(故事片段)
图3.9 房改购房审批流程之“并发汇聚”片段图
如图3.9所示,在“查封核查一”和“查封核查二”两个活动之后,房改购房审批流程通过一个“并发汇聚”网关,继续向下流转到“制证”活动上。
2.上下文(描述、动机)
描述:并发分裂出的多个活动(“查封核查一”和“查封核查二”)全部执行完毕后,后续活动才会被触发。
动机:为通过并发分裂模式创建出的分支提供一种再次汇聚的机制。
3.问题的本质
当活动涉及的资源需要合并处理时,则采用同步机制。这里的资源包括某些成果的合并(例如,两个核查结果做合并)。
4.解决方案及技术实现
解决方案。由于此模式一般都与并发分裂模式配对使用。对应于并发分裂模式中的显式方案和隐式方案,此模式的解决方案同样分为显式方案与隐式方案,如图3.10和图3.11所示。
图3.10 同步模式的显式实现方案
图3.11 并发汇聚(同步)模式的隐式实现方案
技术实现。在此模式中,显式方案与隐式方案的实现稍有不同。
(1) 定义期:对于显式方案(如图3.10),直接在设计器中提供AndJoin活动节点即可,不需要另外设置。而对于隐式方案(如图3.11),由于同步模式要求所有参与汇聚的节点必须全部完成才能触发后续分支,因此必须在“任务D”上设置同步等待的标志(或者称之为“与汇聚”标志)。
(2) 运行期:如图3.12所示,对于“活动D”这个对象,其属性incomingTransitions是一个集合,集合中包含id=”tran_3”和id=”tran_4”的两个转移对象,当两个转移对象都执行完毕时,触发活动D的执行,即可实现同步模式。
图3.12 并发汇聚(同步)模式的隐式方案对象关系图
5.约束及可能存在的问题
与并发分裂模式中的驳回相对应,此模式同样存在驳回问题:如果并发需要驳回,则必须采用多选汇聚模式来代替同步模式,才能满足驳回需求。
6.规范中的实现
XPDL 2.1中的实现
<WorkflowProcess Id="b8043656-a95c-40e4-917e-2919a59fbfb3" Name="Process 1"> <Activities> <Activity Id="1c38df40-d035-4155-b473-d81fa606c2a8" Name="活动B"> <Description /> <Implementation> <Task /> </Implementation> </Activity> <Activity Id="d666bc95-edda-446f-9f93-98f27c53a7f8" Name="活动C"> <Description /> <Implementation> <Task /> </Implementation> </Activity> <Activity Id="b2fc7f93-aca6-4d52-965a-432553f02c9c" Name="并发汇聚网关"> <Description /> <Route GatewayType="AND" /> </Activity> <Activity Id="194e2c59-9218-49d5-baf4-e9feb715d9f0" Name="活动D"> <Description /> <Implementation> <Task /> </Implementation> </Activity> </Activities> <Transitions> <Transition Id="a6a47f65-cc0d-4302-870a-5f43556be0e4"
From="1c38df40-d035-4155-b473-d81fa606c2a8" To="b2fc7f93-aca6-4d52-965a-432553f02c9c" Name=""> <Condition /> </Transition> <Transition Id="fe10657f-542a-4229-be3a-382b4aa2a7ad"
From="d666bc95-edda-446f-9f93-98f27c53a7f8" To="b2fc7f93-aca6-4d52-965a-432553f02c9c" Name=""> <Condition /> </Transition> <Transition Id="735397b6-fb5f-4712-a944-59760458403c"
From="b2fc7f93-aca6-4d52-965a-432553f02c9c" To="194e2c59-9218-49d5-baf4-e9feb715d9f0" Name=""> <Condition /> </Transition> </Transitions> <ExtendedAttributes /> </WorkflowProcess> |
如上所示,在XPDL规范中,采用的是显式同步方案。
BPEL 2.0中的实现(XML内容由Eclipse BPEL Designer 生成,去掉了与控制模式无关的属性)
同样采用<flow></flow>标签进行实现。
<bpel:process name="ParallelPattern" targetNamespace="http://sample.bpel.org/bpel/sample" suppressJoinFailure="yes" xmlns:tns="http://sample.bpel.org/bpel/sample" xmlns:bpel="http://docs.oasis-open.org/wsbpel/2.0/process/executable" > <bpel:sequence name="main"> <bpel:empty name="Empty"></bpel:empty> <bpel:flow name="Flow"> <bpel:invoke name="Invoke1"></bpel:invoke> <bpel:invoke name="Invoke2"></bpel:invoke> </bpel:flow> <bpel:invoke name="Invoke"></bpel:invoke> </bpel:sequence> </bpel:process> |
BPMN 2.0中的实现(XML内容由Signavio Process Editor导出,去掉了与控制模式无关的属性)
<process id="sid-921359f3-d331-4fa7-aad9-7a6eb6e32d4a" isExecutable="false"> <task completionQuantity="1"
id="sid-4038BF10-88DD-4CD4-B51E-2A56B30D372F" isForCompensation="false" name="活动B" startQuantity="1"> <outgoing>sid-C3C65849-94FE-4D2A-B5F9-500BF6F01C6A</outgoing> </task> <parallelGateway gatewayDirection="Converging"
id="sid-AA7B31AA-C305-4B94-B48B-BA695B497FBD" name="并发汇聚网关"> <incoming>sid-C3C65849-94FE-4D2A-B5F9-500BF6F01C6A</incoming> <incoming>sid-D2F19E17-1F1E-4234-AF1C-D5F85D99AE2D</incoming> <outgoing>sid-8275F97F-34DB-4E4F-B73B-72FA44CAE1F5</outgoing> </parallelGateway> <task completionQuantity="1"
id="sid-7E91DCFB-7845-48A6-8263-842B46D0744C" isForCompensation="false" name="活动C" startQuantity="1"> <outgoing>sid-D2F19E17-1F1E-4234-AF1C-D5F85D99AE2D</outgoing> </task> <task completionQuantity="1"
id="sid-225CB518-1A4E-46A5-80D1-DAF2143B5233" isForCompensation="false" name="活动D" startQuantity="1"> <incoming>sid-8275F97F-34DB-4E4F-B73B-72FA44CAE1F5</incoming> </task> <sequenceFlow id="sid-C3C65849-94FE-4D2A-B5F9-500BF6F01C6A"
name="" sourceRef="sid-4038BF10-88DD-4CD4-B51E-2A56B30D372F"
targetRef="sid-AA7B31AA-C305-4B94-B48B-BA695B497FBD"/> <sequenceFlow id="sid-D2F19E17-1F1E-4234-AF1C-D5F85D99AE2D"
name="" sourceRef="sid-7E91DCFB-7845-48A6-8263-842B46D0744C"
targetRef="sid-AA7B31AA-C305-4B94-B48B-BA695B497FBD"/> <sequenceFlow id="sid-8275F97F-34DB-4E4F-B73B-72FA44CAE1F5"
name="" sourceRef="sid-AA7B31AA-C305-4B94-B48B-BA695B497FBD"
targetRef="sid-225CB518-1A4E-46A5-80D1-DAF2143B5233"/> </process> |
如上所示,BPMN规范同样采用的是显式同步模式方案。
7.与其他模式的关系
一般与并发分裂模式配对使用。
|