内容


IBM WebSphere 开发者技术期刊

流程反模式:如何避免业务流程建模中的常见陷阱,第 1 部分

控制流建模

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: IBM WebSphere 开发者技术期刊

敬请期待该系列的后续内容。

此内容是该系列的一部分:IBM WebSphere 开发者技术期刊

敬请期待该系列的后续内容。

摘自 IBM WebSphere 开发者技术期刊

引言

随着越来越多的人参与到业务流程建模项目中,业务流程建模在软件开发社区中的地位也与日攀升。不仅如此,在业务流程建模项目中,具有不同专业背景的人员也越来越多。业务流程是组织中最重要的资产之一。现在,很多企业开始基于面向服务的体系结构 [4] 来构建自己的 IT 系统,业务流程逐渐成为支持 IT 系统的“一等公民”。业务流程建模已不再是为备案和讨论而进行的建模练习,它已演变成了业务驱动开发 [10, 14] 的直接动力。因此,流程模型对 IT 系统和企业操作效率的影响越来越大,进而也增加了使用设计不当的流程模型 [2, 7, 8] 所带来的经济风险。

遗憾的是,目前还没有一种很好的方式能对业务流程模型的质量进行有效度量。通常情况下,基础流程本身采用成本和利润等经济关键性能指标加以度量。一流的建模工具应能够提供强大的分析功能来挖掘流程的经济效应。但是,现在的大多数分析工具都不能满足这些质量要求。有时,由于模型中仍存在尚未检测到的隐藏错误,其分析结果甚至可能是错误的。

当代文献回顾

在科学文献中检索相关著作时,我们发现只有屈指可数的几篇文章论述了流程模型的质量度量问题。Guidelines of business process modelingKomplexit?tsmanagement in Prozessmodellen[2, 17] 创立了六条建模准则(或原则):正确相关、经济、明确、可比较设计系统。但是,它们并未给出任何可以计量的标准,无法让工具以客观的方式直接度量流程模型的质量。

Guceglioglu 和 Demirors 的研究 [7, 8] 中,他们采用 ISO/IEC 9126 软件产品质量模型并基于功能性可靠性可用性可维护性 来度量流程模型的质量。目前,相关的专家必须使用主观评估来估算这些度量指标,例如,评估流程模型中的活动在功能上是否可以达到该流程的设计目标。

An experimental investigation of UML modeling conventions 描述了一项试验性研究,其中度量了用户因序列关系图和类关系图 [12] 不一致而导致曲解的程度。它介绍了几种缺陷,这些缺陷侧重于模型的静态和语法方面,但不适用于具体行为,即不适用于流程模型。

模式在工作流社区中占有十分重要的地位,这主要是因为针对工作流模式的前期工作将成为比较工作流引擎的基础,详细信息参见 Workflow patterns[23]。另外,下列著作也对模式在行为模型设计 过程中的作用进行了研究:

关于本文

在本文中,我们为流程模型引入了反模式,以便可以从客观角度度量流程模型质量的一个重要方面。反模式会捕获流程模型中致使模型出错的典型设计错误。Wikipedia 将它们定义为“常见的重复劣质问题解决方案类别[1]

我们所说的正确性是指,在考虑各种因素的情况下,流程模型的执行路线符合用户对流程行为的预期。因此,不正确的模型将表现出非预期和错误的行为,进而增加与这些模型关联的经济风险。此外,不正确的模型通常还会表现为设计缺乏系统性,其功能通常不充分,并可导致实现软件中出现可靠性问题。毫无疑问,不正确的模型还会影响可用性、明晰性、可比较性和可维护性。因此,您需要检测并更正流程模型中的反模式,以提高流程模型的质量并降低与其关联的经济风险。

本文汲取了我们从 2004 到 2006 年间在检查用 IBM® WebSphere® Business Modeler(以下称为“Business Modeler”)和其他建模工具(例如 Aris [21]、Adonis [22] 或 MID Innovator [6])创建的数百个流程模型时得出的经验教训。这些模型都源自实际项目,内容涉及银行、保险、零售、制药以及电信等多个行业。

在检查这些模型的未发布版本时,我们注意到存在很多重复的建模错误并将它们抽象化为反模式。在本文中,我们将介绍每种反模式的定义,说明此反模式中的模型片断之所以是错误的原因,同时提供正确的模型。在每部分的结尾,我们都会提供建议,并归纳主要观点。我们已在 Business Modeler 中用匿名方式重绘并创建所有模型,换句话说,我们将只显示抽象名称,而并不提供有关示例来源或原始建模工具的信息。在很多情况下,我们还会说明用户在流程建模过程中为什么会不知不觉地出错,同时指出 Business Modeler 中有助于发现这些错误的支持。

本文面向有一定流程建模经验的用户,特别是有 IBM WebSphere Business Modeler 建模经验的用户。本文假设您熟悉官方产品教程或课程中讲授的 Business Modeler 基础知识。我们的大多数反模式都独立于 Business Modeler,它们在其他行为模型的建模语言(例如 UML2 Activity Diagrams (UML2-AD) [16]、Event-Driven Process Chains (EPC) [20] 或最新的 Business Process Modeling Notation (BPMN) [3])中也存在相对应的情况。

本文的组织结构如下:

  • 背景知识介绍了在 Business Modeler 中进行业务流程建模所使用的主要建模元素,同时描述了它们与 UML2-AD、EPC 和 BPMN 中相应元素之间的关系,此外还为介绍各种建模场景的后续部分提供了背景知识。
  • 场景 1:分支行为建模讨论了如何对并行流和可选流进行分支和联接。
  • 场景 2:循环行为建模重点介绍如何对迭代行为建模。

这些部分中介绍的反模式和建议还可能受到采用其他建模符号的用户的关注。

背景知识

本部分将回顾在 Business Modeler 中进行业务流程建模所使用的主要建模元素,同时描述它们与 UML2 Activity Diagrams、Event-Driven Process Chains 和最新的 Business Process Modeling Notation 中的相应元素之间的关系。接下来,我们将介绍 Business Modeler 建模语言的可变性,并引入两种流程模型:使用网关形式 的模型和使用活动形式 的模型,我们将以这两种模型为基础介绍建模解决方案,以应对各种建模场景中的挑战。此外,我们还将介绍反模式和模式所使用的符号。

用于控制流的基本建模元素

本部分将回顾在 Business Modeler 中进行业务流程建模所使用的主要建模元素,同时描述了它们与其他建模符号中的相应元素之间的关系。接下来,我们将介绍 Business Modeler 建模语言的可变性。

IBM WebSphere Business Modeler 中的示例流程模型
IBM WebSphere Business Modeler 中的示例流程模型

让我们对图 1 中的流程进行分析:

  1. 流程从 start 节点开始,它用一个绿色项目符号表示。
  2. 此节点连接到 Task 1,后者用黄色的圆角矩形表示。在 Business Modeler 中,任务是流程的原子 活动,无法进一步细化。
  3. Task 1 后面跟的是引向两个后续分支的 decision。执行此流程时,将只选择一个决策分支,即我们在此处设计的是独占性选择。上面的 Yes 分支引向 fork,后者将在流程流中捕获一个并行分支。这样,此模型中跟在 fork 之后的所有分支(即 Subprocess 1Task 2)都将得到执行。
  4. 在 Business Modeler 中,您还可以使用另一个流程模型进一步细化子流程。子流程和任务是 Business Modeler 中的两种可用活动
  5. 这两个并行分支在 join 处再次联接,从而结束并行执行。
  6. 下面的 No 决策分支将引向 inclusive decision。包含性决策建立的是m 中选 n 模型,此工作流模式已众所周知(详见 Workflow patterns, [23])。这意味着,可以选择执行一个或多个后续分支。在我们的示例中,将可以单独执行 Task 3Task 4,也可以同时执行 Tasks 3Task 4。对于前两个选择,将只导致一条后续执行路径,而同时选择 Task 3Task 4 将导致并行执行这两个分支。
  7. 这两个包含性分支在 merge 处再次合并。
  8. join 元素和 merge 元素连接到另一个 merge,进而与最初的独占性决策匹配。
  9. end 节点终止此流程模型。

您可以使用 Business Modeler 的模拟功能来可视化并分析流程的可能执行路线,以了解决策中的控制如何分支,以及它如何在 fork 后进行并行执行。

图 2 显示了使用 IBM® Rational® Software Architect [9] 建模为 UML2 Activity Diagram (UML2-AD) [16] 的同一流程。

建模为 UML2 Activity Diagram 的同一示例流程
建模为 UML2 Activity Diagram 的同一示例流程

由于 Business Modeler 和 Rational Software Architect 之间可以无缝集成,因而软件架构师可通过业务建模的 UML 2.0 概要[9] 用 UML2 符号可视化流程模型。此概要可在业务流程模型与现有或新增的 UML2 模型之间提供互换语义。基于这些语义,我们在表 1 中列出了相对应的元素。

表 1. Business Modeler 与 UML2-AD 符号之间的元素映射
Business Modeler 中的元素UML 2.0 Activity Diagrams 中的元素
StartInitial
EndFlow final
TaskCall behavior
SubprocessStructured activity
ForkFork
JoinJoin
(Exclusive) decisionDecision
MergeMerge
Inclusive decision(Decision)

用户在直接建立活动关系图时,通常还会建立一个 action 来代替 call behavior 并将 structured activity 替换为 call behavior。在 UML2-AD 中并不存在包含性决策,与之相映射的是 UML2 决策,此决策是独占性的。因此,我们在模型中显式添加了 Task 3Task 4 并行执行的情况。我们使用了一个 fork 和一个 join,并将任务的其他副本置于两者之间。

图 3 显示了用 Maestro [19] 工具建立的示例流程模型,此工具实现的是由 OMG [3] 定义的最新标准符号 Business Process Modeling Notation (BPMN)。

用 BPMN 建立的示例流程模型
用 BPMN 建立的示例流程模型

让我们分析一下此图。与上面的建模方法类似,BPMN 在关系图中也区分任务子流程,且后者由圆角矩形中的“+”符号表示。

  1. 流程开始由 start event 指示,而流程末尾则标记为 end event
  2. 流程的控制流行为用 gateway 设计。
  3. 可选分支用 exclusive (XOR) gateway 建立,它显示为一个菱形,也可以用“X”标记。
  4. 包含分支用 inclusive (OR) gateway 建立,它显示为一个内含圆形的菱形。
  5. 并行分支用 parallel (AND) gateway 建立,它显示为一个包含“+”的菱形。BPMN 并不提供任何单独的建模元素来联接或合并流程模型中的多个分支。它只使用相同的符号对流程流进行分支、联接或合并。

最后,我们使用 Aris Business Architect [21] 将此示例流程建模为 Event-Driven Process Chain (EPC)。与前面的方法相比,EPC 更多的是以自上而下的方式绘制。

建模为 Event-Driven Process Chain 的示例流程的控制流
建模为 Event-Driven Process Chain 的示例流程的控制流

现在,我们将继续对图 4 中的关系图进行分析:

  1. 此流程以 Start event 开始并以一个名为 Process End Event 的事件结尾。EPC 并不区分结束事件的具体类型,而是让用户决定如何结束流程。
  2. 各个任务由 function 表示。
  3. 子流程用 process interface 捕获,后者是一个函数,可使用其他 EPC 模型进一步细化。
  4. 在每个函数后,我们并未向模型中引入任何其他事件。虽然这在 EPC 方法中十分常见,但在其他方法中,事件的表示形式则大相径庭。
  5. fork 对应于 AND Rule,inclusive decision 对应于 OR Rule,而 decision 则对应于 XOR Rule。与 BPMN 类似的是,EPC 也使用相同的规则符号来打开和关闭流程流中的分支。

从上面可以看出,虽然不同建模方法的图形符号存在差异,但用于建立控制流模型的主要元素却十分相似。因此,下面的反模式同样适用于采用其他建模方法的用户。在以下部分中,我们将重点关注 IBM WebSphere Business Modeler。

流程模型的网关形式和活动形式

在上一部分中,我们使用不同的建模方法对同一流程进行了建模。其中每个模型都利用控制节点(Business Modeler 和 UML2-AD)、规则 (EPC) 或网关 (BPMN) 来捕获控制流。由于 BPMN 标准使用网关一词,因此当我们提到 Business Modeler 中的 decision、fork、merge 和 join 建模元素时,我们将统称为“网关”。

除网关外,其中的部分建模语言(我们将只关注 Business Modeler)还提供了建立控制流和数据流模型的另一种可选方法。此可选方法基于活动(即任务和子流程)的输入和输出建模。这些输入和输出可以是纯控制流链接(类似于上一部分中的模型),也可以是类似于图 5 所示的数据流链接。

在 Business Modeler 中,通过将控制流与所谓的业务项 关联在一起,可以将其更改为数据流。业务项用于捕获流经流程的信息类型或数据对象。用户可以随意选择这些业务项的名称,并可通过添加属性进一步细化它们的说明。在将业务项从一个任务发送至另一个任务后,将无法更改它的类型,也就是说,输出、输入以及它们之间的连接始终与相同的业务项关联。

图 5 显示的 Task 1 具有三种不同的输入(类型分别为 ABC)和三种不同的输出(一个控制流输出,另外两个的类型分别为 B C)。

任务的输入和输出条件
任务的输入和输出条件

对于输入,我们定义了三种不同的输入条件,此外还定义了两种不同的输出条件。条件用于指定 Task 1 的可选输入和输出集。如果它同时收到所有这三个输入(即 ABC),或者只收到 B C 的组合或 A C 的组合,将执行此任务。在输出中,它将提供 B C 的组合或只提供控制输出。因此,这些条件与网关相似,也用于描述分支和联接行为。

您需要在 Business Modeler 的高级编辑模式中才能正确定义所需的输入和输出条件。此编辑模式在 Attributes 视图中提供了 Input Logic 和 Output Logic 选项卡。图 5 中带有蓝色边框的屏幕快照就是从这两个选项卡中提取出来的。在此图中,Task 1 输入和输出下方有一些灰色和黑色的逆向/顺向箭头,表示我们为该任务定义了多个输入和输出条件。如果只定义一个输入和输出条件,图中将不会显示任何箭头,并且通常也不显示带有蓝色边框的选项卡。基本编辑模式会隐藏所有这些详细信息,包括其中的箭头。

当活动收到至少一个输入条件的所有必需输入后,便可以执行该活动,否则它将等待这些输入到来。当活动执行时,它将正好产生一个输入条件的所有输出。它选择的输出条件取决于激活该活动的输入条件。在 Business Modeler 中,您可以通过关联输出条件与输入条件来为此依赖关系建模。如果未为此类关联显式建模,该活动将以非确定的方式产生一种输出条件。

当我们说流程模型采用网关形式 时,是指该流程模型只使用网关(在其他建模语言中称为控制节点或规则),但一个任务或子流程只有一个输入和输出条件。如果流程模型在活动中使用多个输入和输出条件,但并不使用网关,则表明它采用的是活动形式

图 6 显示了采用网关形式的流程模型。利用网关形式,模型中的分支和联接点会更加明确。此外,我们还可以编辑决策节点的输出逻辑,从而更加方便地向该节点分配显式决策条件。

显示采用网关形式的控制流的流程模型
显示采用网关形式的控制流的流程模型

图 7 采用活动形式捕获相同的控制流。在活动形式中,决策条件将被捕获为输出条件的后置条件。活动形式的优点在于,它不仅可以让模型更加简洁,还可以减少流程中的建模元素,而只使用功能性活动。不过与使用网关相比,使用和定义输入/输出条件会更加困难,因而此形式又使流逻辑的捕获过程变得更为复杂。

使用活动形式建模的同一流程
使用活动形式建模的同一流程

在图 7 中,Task 1 充当 decision,而 Task 4 则充当组合的 merge 和 fork。Decision 和 merge 始终映射到多个输入和输出条件,每个分支对应一个条件,而 fork 和 join 则分别对应于一个输出和输入条件。

对于仅显示控制流的模型,这两种形式可以互换,模型将保留其本身的语义。但是,这只适用于控制流。数据流包含重要的语义差别,我们将在本系列的第 2 部分中对此进行详细讨论。

建议

  • 请尝试在您的模型中采用这两种形式之一,以减少使用的模型元素数。此技术将引出更为相似的建模风格:
    • 网关形式使用 decision、fork、merge 和 join 元素,对于只包含控制流的模型而言,此形式通常更易于理解。
    • 活动形式使用输入和输出条件,但不使用网关。它将分支逻辑隐藏在输入和输出条件中,因而更适于简化流程模型的可视化形式。
  • 在 Business Modeler 中,对于采用活动形式 的模型,您可以使用高级编辑模式 来查看其分支流的详细信息,但在基本编辑模式 中,这些信息将处于隐藏状态。
  • 请尝试在单个关系图中混合使用这两种形式。对于数据流模型,您可能需要采用混合方式,但对于控制流模型则不必如此。

模式和反模式的概念

在描述各个建模场景时,我们首先会提供一个展示错误的示例,然后再将其归纳为反模式。此外,我们还将以模式的形式显示针对反模式的更正。为描述模式和反模式,我们将使用类似于图 8 所示的流程片断:

流程片断符号
流程片断符号

此图显示了我们的两种符号:

  • 如果活动内外的数据或控制流与理解导致建模错误的原因有关,我们将使用此图上半部分中的符号。在此流程片断中,Task 1 接收输入 A B 并提供输出 A B,而 Task 2 则接收输入 A C 并提供输出 A DTask 1 在流中位于 Task 2 之前,但在这两个任务之间,还可以建立一个任意的流程片断。 此任意的流程片断由虚线框表示。
  • 如果附加到流中的数据是无关数据,我们将只使用蓝色箭头表示流方向。图 8 的下半部分显示了此符号的示例,其中使用了 Task 3Task 4

对于特定的流程模型,您可以将其某个片断与反模式中显示的流程片断加以比较,以此来查找其中的错误。此外,您还可以使用本文提供的模式来更正匹配的流程片断。反模式通常都在左上角标记一个大红叉,而模式则用绿色的对勾标记。此外,我们还使用红色的虚线圆来突出显示导致错误的建模元素,并用橙色的虚线圆突出显示不推荐使用的建模元素。

场景 1:分支行为建模

很多业务流程模型都需要显示控制流和数据流在流程中是如何分支和联接的。Business Modeler 提供了 decisioninclusive decisionfork 网关来描述可选分支和并行(并发)分支,同时又提供了 mergejoin 网关来描述流程中的可选联接和并行联接。从原则上说,您可以在流程模型中随意组合这些网关。但是,在模拟流程模型时,其中的部分组合会导致执行问题。在以下部分中,我们将对各个网关进行系统研究。

因 decision-join 对导致的死锁

图 9 显示了流程模型中经常出现的两种典型的 decision-join 对。在开始节点后,紧跟一个 decision,它表示流程流中的三个可选分支,这些分支最终引向 Task 5 之前的 join。此结构将导致流程中出现死锁,因为该 decision 只在它的一个分支上发出输出,而 join 将在其所有分支上等待输入。此输入将永远不会出现,因此 join 将一直等待缺少的输入而无法执行。在此情况下,很明显会发生死锁。死锁始终是一个建模错误:因为流程中无法执行某些活动,所需的部分流程行为丢失。利用 Business Modeler 的模拟功能,您可以方便地检测出此错误行为:在模拟过程中,将永远不会执行 Task 5

因 decision 后跟有 join 或活动中存在不适当的输入和输出条件对而导致的死锁
因 decision 后跟有 join 或活动中存在不适当的输入和输出条件对而导致的死锁

在此示例中,Task 3Task 4 之间又会发生另一处死锁。Task 3 将产生 A B 作为两个独立输出条件的可选输出,即它的行为类似于独占性决策。Task 4 要求同时将 A B 用作单个输入条件的输入。在此流程的任意执行过程中,将永远不会产生这两个输入,因而无法执行 Task 4。这样,当 decision 选择执行最下方的分支时,我们将又一次遇到死锁。对于此情况,您仍可以在流程模拟期间将其检测出来。

decision 及其后续 join 的组合是业务流程模型中最常出现的反模式之一。显然,很多用户并不完全了解这些网关的语义以及因此错误组合而导致的行为。在上面的示例中,死锁比较容易发现。但在大型示例中,分支逻辑可能会非常复杂并包含多种不同的活动和网关,从而使用户更难以发现这些问题。因此,在组织流程模型时,应始终保持结构清晰,同时从我们前面介绍的活动形式网关形式 中选择一种。

图 10 中的反模式显示了一种因错误的 decision-join 对而导致死锁的普遍情况。

反模式:导致死锁的 decision-join 错误组合
反模式:导致死锁的 decision-join 错误组合

decision 有两个传出分支,它们的所有连接末端都用作 join 的输入分支。当然,decision 也可以有两个以上的分支。只要离开 decision 的分支只有一部分被 join 重新联接,就同样会发生死锁。我们在此处显示了一些控制流,旨在强调包含控制流和/或数据流的模型都可能出现反模式,同时也是为了演示单个分支中的连接如何与反模式中的网关连接在一起。对于此反模式,使用活动形式 的变种非常简单,本文将不再演示。

因 fork-merge 对导致的缺乏同步

图 11 显示的 fork-merge 对表现出与 decision-join 反模式相反的行为。

因 fork 后跟有 merge 而导致的缺乏同步
因 fork 后跟有 merge 而导致的缺乏同步

fork-merge 对会导致为要执行的 merge 后的所有任务和子流程生成过多的实例,因为 fork 将在它的所有传出分支上发出输出,而 merge 则只等待其中一个分支上的输入。这意味着,对于 fork 的每个分支,merge 都将执行并触发流程模型中的下游活动。在工作流文献中,此反模式通常称为缺乏同步[18, 24],因为对于在 merge 之前对流程片断的单次执行,我们会在 merge 之后多次执行该流程片断。有时您可能需要此行为,但在大多数情况下,此问题是在不经意间引入模型中的。如果出现的流程行为超过需要,则缺乏同步便是一个建模错误,但它并非始终是一个错误,这一点与死锁不同。

在图 11 中,我们可以找到三个导致缺乏同步的元素对。Task 1 后的 inclusive decision 引向 Task 4 之前的 merge。开始节点后的 fork 引向 Task 7 之前的 merge。Task 5 的单个输出条件连接到 Task 6 的两个独立输入条件。这意味着,对于包含 Task 1、2、3、4、5、6 的流程片断的单次执行,我们至少会执行 Task 7 两次。对于 Task 2Task 3 的单次并行执行,我们将执行 Task 4 两次。最后,对于 Task 5 的单次执行,我们将执行 Task 6 两次。

inclusive decision 可在抽象级别捕获 m 中选 n 的选择[23],即在此示例中,inclusive decision 可触发两个分支中的任意一个。如果全部触发这两个分支,则包含性决策将导致 Task 2Task 3 并行执行,其效果与 fork 类似。因此,相应 merge 后的 Task 7 将执行两次,即对每个触发的分支执行一次。Business Modeler 帮助页中的官方建议是始终将 inclusive decision 与 merge 组对。使用 merge 会导致缺乏同步,因为对于每个传入分支,都会触发一次 merge,从而会将 merge 之后的所有任务执行多次。使用 join 不能解决此问题,因为 join 会始终等待所有传入连接。它将阻止 inclusive decision 只选择分支子集的任何模拟运行,即发生死锁。

图 12 中的反模式捕获了导致缺乏同步的错误 fork-merge 对。

反模式:导致缺乏同步的 fork-merge 错误组合
反模式:导致缺乏同步的 fork-merge 错误组合

fork 的每个传出分支都将其连接末端用作 merge 的传入分支。同样,即使至少两个分支的子集以 merge 结尾,也会出现缺乏同步问题。此反模式也是最常见的建模错误之一。在较大的流程模型中,将难以发现此类组合,特别是当它们以 inclusive decision 或活动的输入和输出条件等更加隐蔽的方式出现时,将更是如此。

更正 decision-merge 和 fork-join 对中的分支

下列模式显示了可使用的正确网关对,以便构建形式更加良好的流程模型,从而降低其包含死锁或缺乏同步等问题的可能性。这两个模式描述了正确的 decision-merge 和 fork-join 对。请注意这两个相似的图形如何正确匹配网关,以便于您选择正确的对。图 13 中的模式展示了使用匹配的 decision-merge 对建立可选分支模型的正确方法。

模式:将 decision 和 merge 组对是建立可选分支模型的正确方法
模式:将 decision 和 merge 组对是建立可选分支模型的正确方法

图 14 中的模式展示了使用匹配的 fork-join 对建立并行分支模型的正确方法。

将 fork 和 join 组对是建立并行分支和联接模型的正确方法
将 fork 和 join 组对是建立并行分支和联接模型的正确方法

请注意,与 decision 组对的匹配 merge 独立于位于这两个网关之间的流程片断。fork 和 join 的情况也是如此。另外,对于 decision 中的每个输出条件,merge 中还都存在一个匹配的输入条件,这样,从每个输出条件开始的所有连接都将以同一输入条件结尾。同理,此要求也适用于 fork 和 join 之间的连接。decision 和 merge 以及 fork 和 join 之间的所有输入都必须连接在一起。

我们建议始终按照相应的对使用网关。这意味着,每个 decision 最终都应跟随一个匹配的 merge,并由后者组合从 decision 开始的所有路径。同理,每个 fork 最终也都应跟随一个匹配的 join,并由后者组合从 fork 开始的所有路径。利用这些模式,可设计出形式良好的模型结构,从而避免因随意使用网关而导致的建模错误。有时,此技术可能导致很多匹配的对,造成多个 merge 或 join 接连出现,从而会给流程模型增加不必要的冗余。

在此类情况下,请用一个 merge 关闭几个 decision 并用一个 join 关闭几个 fork,这样便可产生正确的模型。图 15 显示了采用此类“速记”符号的典型流程模型。此示例使用单个 merge,而不是在模型中添加三个连续的 merge。但是,在同时包含两类分支(即 fork 和 decision)的模型中,使用此类解决方案应十分谨慎,以避免在不经意间用一个 join 关闭一个 fork 或用一个 merge 关闭一个 decision。

用单个 merge 正确关闭与之匹配的所有分支
用单个 merge 正确关闭与之匹配的所有分支

冗余分支

在此部分中,我们将对流程中的冗余问题进行更深入的研究,并在此基础上得出结论。图 16 显示的流程模型使用两个接连出现的 merge 关闭了具有四个分支的 decision。

导致执行相同后续任务的冗余“功能相同”分支与“无用”分支的对比
导致执行相同后续任务的冗余“功能相同”分支与“无用”分支的对比

第二个和第三个分支都引向 Task 2,它们在 decision 和第一个 merge 之间不执行任何活动。这两个分支相互区别的原因并不明显,除非建模人员希望分隔 decision 条件,这在使用流程监视的应用程序中可能会有此要求。否则,此差别将显示为冗余,因为同一行为被建模两次,即对于这两个 decision 分支中的任何一个,都将执行单个 Task 2。最下方的分支表示“无用”情况,这在 decision 中可能会有一定意义。与此相比,“功能相同”分支既可能指示模型中存在冗余,也可能说明建模项目尚未完成。

建议

  • 切勿将 decision 与 join 组对。
  • 切勿组合使用 fork 与 merge,除非您想引入缺乏同步。
  • 始终将 decision-merge 和 fork-join 对用作匹配的对,并尽量设计形式良好的模型。
  • 如果将 inclusive decision 与 merge 组对,则在要并行执行多个分支时,inclusive decision 将导致缺乏同步问题。安全的解决方案是避免使用 inclusive decision,并使用 decision 和 fork 显式建立所有可能的分支组合。如果无法避免使用 inclusive decision,则在使用时应十分小心。同时,在实现模型时应特别注意,以确保在细化的 IT 级模型中能正确捕获控制流逻辑。
  • 如果流程模型中的控制流或数据流仅连接两个网关而不执行任何活动,或者它们会导致执行同一活动,则应检查是否存在冗余。

场景 2:循环行为建模

在此建模场景中,我们将讨论流程模型中的循环(迭代)行为的表示形式。在实际流程中,通常需要基于某个决策成果来重复前面的活动。这会导致流程片断多次执行,通常是持续到满足一定的退出条件为止。某些流程模型甚至需要展示无限次执行的行为。在 Business Modeler 中,循环行为可通过多种方式捕获,如图 17 所示。

流程模型中用于捕获循环行为的建模元素
流程模型中用于捕获循环行为的建模元素

此图的上半部分显示了三种建模元素,分别表示 while loopdo-while loopfor loop。重复的流程片断必须置于这些循环建模元素内。这些元素的技术性很强,实际上并不适用于业务用户。业务用户通常绘制逆向连接来将流引回上游活动,如此图的下半部分所示。

此流程模型包含两个逆向连接,其中一个从 Task 1 开始并引回相同的任务,从而实现自循环;另一个从 Task 3 开始并引回 Task 2,导致循环执行这两个任务之间的流程片断。这些逆向连接使用起来非常直观,并通常会导致模型中出现重叠的循环,例如从 Task 1Task 3 再返回 Task 2 的循环与仅涉及 Task 2Task 3 的循环重叠。

在向流程模型中添加此类非结构化循环时,将出现典型错误。值得注意的问题与循环流的正确分支和合并有关。有趣的是,我们只要继续讨论上一部分中的网关,即可方便地描述这些建模错误。在这里,我们只需更改这些网关对的顺序。在上一部分中,我们讨论了用于描述可选流和并行流的网关对,指出 decision 或 fork 应始终位于 merge 或 join 之前。通过调换此顺序便可创建循环,即将 merge 或 join 与 decision 或 fork 组合。在这些组合中,只有一个有效,其余三个都会导致反模式。

因 join-fork 和 join-decision 对导致的循环死锁

图 18 显示了具有三个循环的流程。

因逆向连接以类似 join 的建模元素结尾而导致的死锁
因逆向连接以类似 join 的建模元素结尾而导致的死锁

在第一个循环中,有一个逆向连接从 decision 开始并引回位于开始节点之后的 join。它包含 Task 1。第二个循环是 Task 2 的自循环,它采用活动形式。Task 2 具有一个输入条件,其中接入了两个连接,可充当隐式的 join。此外,它还具有一个输出条件,其中两个连接由此开始,可充当隐式的 fork。我们在第 2 部分的讨论中已经知道,Task 2 将等待此单个输入条件的所有输入。但是,这两个输入无法同时到达,因为其中一个输入是作为 Task 2 的输出产生的。

第三个循环从结束节点之前的 fork 中开始,并引回 decision 之后的 join。它也包含 Task 2。join 将等待其所有分支上的输入。但是,它的一个传入分支只有在 join 执行后才能收到输入,因为它的输入源自模型中的下游建模元素。join 和 decision 以及 join 和 fork 之间的这种循环依赖关系(其中 join 必须在 decision 或 fork 之前执行,反之亦然)便是发生死锁的原因。这些错误建模的循环在下面两个反模式中更加明显。

图 19 中的反模式展示了发生死锁的 join-decision 对。

反模式:导致循环死锁的 join-decision 错误组合
反模式:导致循环死锁的 join-decision 错误组合

此循环包含的 join 位于 decision 之前。join 至少有一个传入分支连接到 decision 的传出分支。一个分支可包含多个连接。

图 20 中的反模式与上一反模式相似,只不过它包含的是 fork 而不是 decision。它与图 19 中的循环依赖关系的类型完全相同,但现在涉及的是 join 和 fork。

反模式:始终导致循环死锁的错误 join-fork 对
反模式:始终导致循环死锁的错误 join-fork 对

在采用活动形式的流程模型中,这些反模式的变种非常简单,本文将不再演示。如果您正在 Business Modeler 的基本编辑模式下工作,请观察图 17 中的循环,其中 Task 1Task 2 将无法执行,因为这些任务将两个传入连接联接在单个输入条件中,因而其行为将类似于 join。由于在基本编辑模式下无法定义所需的可选输入条件,因此在该模式中绘制的大多数逆向连接都会导致模型死锁。在较大的流程模型中,将难以查找死锁循环。需特别指出的是,当流程模型包含的可选分支和并行分支组合了循环时,模型中出现死锁的风险将非常高。我们认为,在迭代中组合了分支行为的模型最为复杂,因为它们既难以绘制,又不易理解。设计形式良好的循环嵌套和流程片断分支,将是降低出现建模错误的可能性的有效方式。

因 merge-fork 对导致循环缺乏同步

在循环模型中,如果分支包含并行执行的逆向连接,但在向流程模型添加逆向连接之前未用 join 对它们进行同步,则会发生缺乏同步问题。在此情况下,每个逆向连接都将由相同的 fork 或活动的输出条件产生,并以 merge 或模型中上游活动的不同输入条件结尾。图 21 显示了一个 inclusive decision,其中两个分支连接回上游的 merge,即每个分支都在流程中导致独立的循环,因为 merge 将单独执行每个传入分支。

从 inclusive decision 或 fork 开始的逆向连接导致多个未同步循环
从 inclusive decision 或 fork 开始的逆向连接导致多个未同步循环

此错误可导致流程中的无控制迭代激增(本示例中为 Task 1 的迭代),此情况有时可使用 Business Modeler 模拟检测出来。如果模拟选择执行 inclusive decision 的多个传出分支,并出现并行循环,则 Business Modeler 便可以检测到此问题。inclusive decision 最上方的分支使用 fork 之前的 merge 连接到第三个循环流程片断。

在模拟期间,Task 4Task 5 的无控制迭代将显现出来,因为每次执行 fork 将得到两个传出分支,因此其相应的 merge 将执行两次。包含 Task 4Task 5 的循环流程片断将以并行方式无限运行下去,其循环中将包括 Tasks 1、2、3

图 22 中的反模式通过 fork-merge 对导致的未同步循环显式定义了缺乏同步问题。

反模式:因 fork 连接回 merge 而导致循环缺乏同步
反模式:因 fork 连接回 merge 而导致循环缺乏同步

流程开始运行时,将触发 fork,后者将引向两个传出的并行分支。其中一个分支引向某个任意流程片断,在此图中并未显示。另一个分支将导致 fork 和 merge 之间的循环。当此逆向分支进入 merge 时,将执行 merge 并再次触发 fork,后者又会激活它的两个传出分支。其中一个分支继而引向此循环的另一次迭代。通过将 fork 替换为 inclusive decision 或具有源自同一输出条件的多个传出连接的活动,可以定义此反模式的两个相关变种。fork 和 inclusive decision 之间的行为差异在于,在执行 fork 和 inclusive decision 时所触发的未同步循环的数目不同。如果 inclusive decision 激活了它的多个传出分支,则只会导致缺乏同步问题。

merge-decision 对的正确循环

要正确建立循环模型,请在 merge 后使用 decision,如图 23 中的模式所示。

模式:使用逆向连接建立迭代行为的正确方法
模式:使用逆向连接建立迭代行为的正确方法

在此模式中,merge 及其匹配的 decision 可包含位于这两个网关之间的任意流程片断。merge 必须至少有一个传入分支来自循环流程片断的外部,否则将无法从其他活动到达此流程片断。此外,decision 必须有一个传出分支引向循环流程片断之外的流程片断,否则此循环将无限运行下去,如果此行为不是预期行为,则会导致所谓的活锁 错误。进入 merge 任意分支的所有逆向连接都应源自 decision 的同一分支,只有这样才能避免出现隐式死锁或缺乏同步问题。在活动形式中,此模式的变种可以使用具有多个独立输入和输出条件的活动,即一个条件对应于网关的一个分支。

建议

  • 要正确捕获循环流程,请在流程模型中添加连接上游活动的逆向连接。逆向连接应从 decision 开始并引回 merge。只有此网关对才能产生正确的循环。
  • 另外,循环也可以从活动的单独输出条件开始,并在该活动或其他活动的单独输入条件中结束。

结束语

在本文中,我们讨论了从数百个用不同工具创建的流程模型中提取而来的典型建模错误。随后,我们将这些建模错误分为几个常见的建模场景。本文的第 1 部分介绍了两个场景,主要解决如何在流程模型中设计分支和迭代行为这一问题。我们基于用 decision、merge、fork 和 join 建模元素构建的网关对来描述解决方案。此外,本文还演示了在八种可能的网关组合中,只有三种可以产生正确的模型。我们将其余五种错误的网关组合归纳为五种反模式,以帮助用户系统地检查并提高模型的质量。

在本文的第 2 部分中,我们将讨论另外四种场景。它们涉及如何建立数据流模型,如何表示事件和触发器,如何正确终止流程以及如何在分层流程模型中重用活动。

致谢

非常感谢我们的同事 Thomas Gschwind、Jochen Küster、Cesare Pautasso、Ksenia Ryndina、Michael Wahler、Olaf Zimmermann 以及其他 IBM 专业人员为本文提出的宝贵意见。我们还要感谢很多其他同事,他们发来了自己的模型供我们分析借鉴。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=218442
ArticleTitle=IBM WebSphere 开发者技术期刊: 流程反模式:如何避免业务流程建模中的常见陷阱,第 1 部分
publish-date=04302007