场景建模与交互建模
来源:用户上传
作者:
场景建模的下一步是在活动中引入参与者角色。交互发生的方式对业务流程在顺境和逆境下的执行均有影响。
场景建模的一开始需要对从产生结果所需基本活动流的理解进行抽象。这时还没有角色――只有对所需活动的理解,活动所需、源自流程外部的输入以及活动产生、为其他流程预备的结果。这种抽象理解常常可由分析产生相同结果的其他业务流程得到,如已经讨论过的“通过柜员取款”例子。这个特殊表示法使用UML 20活动符号,它是我们熟悉的流程图的增强版本。
在这个抽象流程视图中,最初的焦点是识别为完成业务流程而必须发生的活动。针对它们中的每个活动,你需要确定它是否需要来自流程外部的输入,以及它是否产生输出到流程外部的结果。
你还得确定所需的活动顺序,并且要非常小心地完成这一步,因为在这里指定的任何顺序都必须随流程的细化而保留。因此,假如多个活动可以同时发生,那么就必须在你的流程描述中清楚地指出这一点。可以使用活动图符号Fork和Join节点来表示这种机制。Fork节点的语义是,在前一个活动完成后,随后的活动允许并行执行。与此相反,Join节点表示只有前面所有活动都结束之后,后面的活动才能开始。参与者角色划分
场景建模的下一步是在活动中引入参与者角色。每个角色由一个活动区(通常称为泳道)表示。每个区使用它代表的参与者名字标出。如果你在使用一个UML建模工具,请记得使用分区的描述(represents)属性引用你在协作中定义的角色。一旦这么做了之后,假如你想重命名一个角色(很可能是由于你细化业务流程定义引起的),你只需编辑协作中的名字即可,所有的分区名将自动更新。
活动职责分配
流程建模接下来的步骤就是将活动放到活动区。将活动放入分区相当于分配职责。它表示扮演那个角色的参与者负责执行这个活动。把活动放入泳道的行为迫使你清晰地理解每个参与者在流程中所做的事。它强制你把抽象活动划分成各个参与者能够执行的具体活动。这些活动分配标识了参与者之间所需的交互,以及这些交互涉及的工件。
抽象的“认证客户”活动变成比较客户提供的PIN和银行记录中与cardID关联的PIN;抽象的“验证鉴权”活动变成查找与卡关联的账户。
虽然余额管理器(即银行)制定与“认证客户”和“验证鉴权”关联的决策,但是其他参与者角色也有各自的职责。客户必须提供cardID(通过插入ATM卡)和输入PIN。柜员(即ATM系统)必须汇总这些信息并把它传给余额管理器。
为了从业务流程的角度更容易处理这些情况,ATM必须与余额管理器进行两次交互。第一次交互,金额支出被鉴权,并且在账户资金上冻结了相应的取款金额。这部分冻结资金防止了其他目的的取款。资金成功支出之后,发生第二次交互,在这次交互中ATM系统报告支出,而余额管理器更新余额并删除冻结资金。因为该账户可能还有其他冻结资金(来自其他交易),支出报告必须和被删除的特定冻结资金相关联。在这个设计中,关于冻结资金的信息和支出鉴权一起返回给ATM系统,冻结资金的标识符随支出报告一起返回。还要注意,冻结账户资金有意地影响了其他业务流程的执行。它还代表了另一种流程间的交互。
案例中的“认证客户”活动说明了,如果不给参与者角色分配活动,就很容易创建出一个实际是两个或多个参与者间协作努力的活动。这种协作活动习惯假设参与者间的对话是清晰可行的一种常常被证明是错误的假设。如果你是第一次设计ATM系统,这种模糊的活动描述可能会让你认为传统形式的证明(如出示驾照)可以作为识别的基础。
通过将活动放人分区来分配职责,你迫使自己去划分各种活动。这使你去探索这些协作的本质,定义各个参与者活动和它们间所需的通信。这种探索通常足以暴露和解决业务流程定义过程中的任何可行性问题。
交互建模
交互发生的方式对业务流程在顺境和逆境下的执行均有影响。你的流程描述要想精确地指出它们在所有条件下的行为,你就必须在设计中清晰地捕获和描述交互。
生产者-消费者交互
事实上,所有交互都采用的是生产者一消费者交互形式。在这种交互中,一个活动产生准备被一个或多个活动消费的工件(在UML符号表示法中称为对象)。这个工件可能是具体事物,如ATM产生的现金或收据;也可能是抽象事物,如来自银行的资金支出请求。当然,在实现设计时,这种抽象通常会有某种具体的表现形式,如消息、数据库记录或甚至是语音通信。
“产生工件”是用活动指向其产生工件(技术上可认为是对象)的箭头(技术上可认为是对象流)来表示的。“消费工件”(可能会有不止一个工件)则被表示成由工件指向每个准备消费它的活动的箭头。工件本身的位置完全没有任何符号上的意义,记住这一点也很重要。因此,工件被画在角色A的活动区或完全在区域之外,图的含义都将保持不变。
严格地说,在分布式系统中,参与者间所有的交互其实都应该被显示成生产者一消费者关系。这是因为,在现实生活中参与者很少直接交互。相反,它们绝大多数时候都是借助某种媒介进行交互,如纸张、电子邮件、系统消息、文件、数据库、包裹、管线或某些其他方法。工件代表了发送者通过媒介传递给接收者的任何事物。例如,ATM系统产生支出请求,它是一条传送给银行的消息。然后,银行产生一个响应,它是一条传回给ATM系统的消息。
同时交互
参与者之间偶尔确实会有直接交互:它们间真正的同时交互。握手就是这种交互的一个例子:两个人同时在做完全互补的动作。在现实中,分布式系统中的参与者极少同时直接交互,例如,即使人们在彼此对话的时候,他或她的声音也要产生别人可以听到的声波(工件)。
了解这两种交互风格的区别非常重要,因为它们可能的出错模式大不相同。在同时交互中,整个交互要么发生,要么不发生――它基本上是一个原子动作。前一个活动的完成时间就是下一个活动的开始时间:要么两个都发生,要么都不发生。但是,如果通过媒介进行交互,那么前一个活动产生某个工件,随后将其传递给下一个活动。这种交互模式有一种同时交互所没有的出错模式:工件的传递可能失败。前一个活动可能确实产生了工件,但是在传递过程中出现问题,导致工件可能永远不会被下一个活动接收到。当你试图设计一个考虑失败情况的健壮流程的时候,这种失败模式的区别是非常重要的。
简化符号
由于失败模式的不同,你应该非常清楚地意识到,假如参与者之间的交互是生产者一消费者交互,那么你的流程应该反映这一点。但是,显示这些工件可能会产生一张非常混乱的活动图。因而,业务流程建模过程中(相对于它的技术实现)常常对此进行简化。这种简化方式就是显示同时交互。
在使用这种简化方式的时候,你必须完全认识到,跨泳道边界的同时交互几乎总是代表生产者-消费者交互。你应该只在记录业务流程的时候才使用这种简化符号。不要在记录支撑业务流程的系统设计中使用它们,因为理解与处理传递工件的机制和相关的失败模式是技术设计的重要内容。
转载注明来源:https://www.xzbu.com/8/view-45963.htm