作者:Pavel Hruby著,wind.deng译
统一建模语言(UML)为描述面向对象系统定义了一系列的标准符号。使用UML增强了领域专家、工作流专家、软件设计者和其他不同背景的专家之间的交流联系。UML可以在普遍的场合使用,对工作流系统的用户而言很直观。除了这些,UML符号具有准确的语义,也就是说可视化的工作流描述可以作为软件规约。本文侧重讨论了如何使用UML来描述工作流管理系统,如何跟踪从业务流程到面向对象软件设计的描述信息,如何用UML可交互工件来结构化项目知识库。
在本文中,我们先来讨论工作流产品的软件设计者和用户对一种通用语言的需要,然后再来介绍如何使用统一建模语言(UML)描述一般的工作流概念,最后希望和搭建一起探讨如何把面向对象软件规约与工作流系统的描述联系起来。
下面我们先来描述一个企业在实现新工作流管理系统时的通常情形:
顾问与用户一起描述一个软件解决方案所支持的企业业务流程。开发队伍获得顾问的描述,但是他们很难理解业务术语,发现其中描述了太多的信息以至于难以用来实现此系统。开发者从技术观点来撰写系统规约,当把这个系统规约呈现在用户面前时,由于过于专业,以至于用户难以理解。然而为了进行下一步的工作,双方被迫接受了这个系统规约。
这种方式很容易导致系统无法达到用户的需求。用户、顾问和开发者通常都不是用同样的语言,这样的交流问题导致难以保证业务流程所有部分很好沟通,并转换为技术性的软件规约。另外,因为使用此系统的实际用户很难全部理解技术性的系统规约,使软件系统变得难以使用。
其挑战性在于能用一种既准确又友好的方法来为业务流程和业务系统建模。用来描述业务流程的每一个符号对用户来说很直观,并有确定的语义,因此开发者可以用它作为一般的描述,甚至用来精确的描述软件系统规约。
UML有着丰富和复杂的符号来描述软件系统。这些符号也许太丰富以至于不直观、不友好。然而,恰当地用UML来描述工作流管理系统有两大好处。首先,UML是软件界公认的符号标准;第二,UML也可用在不需要实现细节的一般场合。在显示的UML图与那些领域专家已经在使用的图在直观上很相近,另外,它们的语义有精确的定义。如有必要,可出于软件设计的目的给同样的图增加详细的实现细节。
业务系统的描述由流程和静态结构的描述组成。流程最直观的模型就是一个活动或任务的序列,按照顺序完成以到达某个目标。因此,UML的序列图和活动图很适用于友好、准确、详细地描述业务流程,如组织图之类的静态结构,没有实现细节,可以用UML的静态结构图描述。图形化的实现细节往往会误导那些不精通UML的人。例如,导航箭头经常错误地表示方向,最好是仅用UML表示选项的某一特定子集。例如,把元素互相嵌套来表示组装比用实心菱形表示关联要好。用文字来描述各种属性,而不用UML符号,例如《refine》就比带三角形的虚线好理解得多。
这里介绍了用UML来描述工作流概念的例子。这仅仅提供了一个一般的指导,如何把工作流概念映像成UML,详细的细节很容易从UML的语义和符号指南[7]得到。工作流管理系统的每个结构都能用合适构造型的UML符号来描述。
图1显示了用UML描述业务流程、业务对象、团队角色。业务对象在UML中用类和对象表示。类描述没有特性(identity)的业务对象,如发票(invoice);对象描述有特性的业务对象,比如编号为VM4/55的发票(VM 4/55: invoice)。业务流程1用用例和用例实例来描述,用例根据目标、职责、前置条件和后置条件来描述;用例对象是具体的事件序列。工作流是自动化的业务流程,用带有构造型 <<workflow>> 的用例或用例实例描述。在UML中用类和对象描述团队角色(team roles),用类来描述团队角色的类型,对象描述担任该角色的具体工人(worker)。所有的符号可以用相应的构造型来修饰,如 <<business object>>、<<business process>>和<<team role>> 。每一个构造型都可以用文字或一个特定的图标表示。
假设业务流程是在业务系统中的业务对象、角色和其他的实例之间协作完成的。请参看详细介绍“跟踪业务流程到软件设计”。
图2显示了一个团队结构的例子。团队的角色用对象实例表示,为每个角色指定了雇员数量。一个客户满意团队(Customer Satisfaction Team)有三个开发员、两个测试员、一个产品经理和一个人担任用户角色。角色组叫做客户满意团队(Customer Satisfaction Team),用包符号表示。角色组也可能被表示成对象——作为角色的组装(composition)。如果团队表示为对象,团队和角色之间的关系为组装关系,那么根据UML元模型概念,一个特定的角色实例不能同时属于多于一个团队。如果团队表示为包,特定的角色实例可以同时属于几个团队。
图3描述了业务流程的实例。角色客户(customer) 下了一份定单,然后销售(sales)部门中的某个工人确认此定单。如果定单有效,此工人调用另一业务流程“公司运输物品(company ships an item)”的实例。这个类型的图在UML表示法指南中没有明确的提到,然而,它符合UML的元模型。在对象生命线顶部的符号代表分类器角色,如图3中的角色、对象角色和用例角色。
图4是UML用例图,描述了业务流程之间的静态关系。业务流程描述组织(organization)与角色客户(customer)的协作。注意在UML的1.1版本中,用例不能相互联系而总是由角色发送信号触发。这给建模环境带来困难,一个用例在运行期间,当特殊条件出现时,另一个用例也开始启动。在这种情况下,角色通过与另一个用例的联系初始化此用例而不需发出任何特定的开始信号。例如,如果客户的请求被评估为有效,用例公司运输物品(company ships an item)被组织中的对象触发。这个用例实例不直接由客户触发,希望下一版本的UML将减少用例间有关联系的限制。
UML用例图不容易表达出用例实例的顺序,例如,首先客户请求一项物品,然后公司将传送此物品,最后客户付款。一个解决的方法就是在用例间使用约束{precedes}或依赖关系
<<precedes>>
。类似的关系同样存在于OML(OPEN modeling language),参看[3],Robert C. Martin建议使用关键字follows替代precedes,参看[6]。这样替代的原因是依赖关系
<<follows>>与依赖关系<<preceds>>的指向相反,依赖关系<<follows>>
指向通常的依赖方向——从依赖元素指向独立元素,至于哪一个更直观仍是个未解决的问题。然而,带约束或依赖的图仍然是静态结构图,并不描述特定场景。
角色可以通过特殊顺序启动用例的方法来使用系统。像这样的场景——用例实例序列——可以用顺序图或协作图描述,参看图5和图6。对照对象交互图,场景被描述为消息序列,用例交互图把场景描述为用例序列。这个图仅仅是由其他场景的实例组成的一个场景的UML图。在图5中消息调用(invoke)表示用例构造器和映射为从角色到用例的信号。根据每个用例的最开始操作,如调用请求(invoke request), 调用运输(invoke shipment)和调用付款(invoke payment),可以命名这些消息,除了这些消息之外,用例交互图能表示角色与系统间其他消息的交互,并描述了用例与角色的全部交谈。
用例协作图也描述业务流程实例组成的一个场景。不象用例序列图,用例协作图描述用例实例和角色实例之间的用例关系和消息交互。用例协作图如图6所示。
用例交互图描述的仅仅是由用例实例组成的一种典型场景。因此它不能表达用例实例所有允许的顺序,属于用例包的用例实例所允许的顺序可以在用例包生命周期内详细说明。用例包的生命周期可用静态图、Backus-Naur范式(BNF)(请参看[4]如何使用BNF指定生命周期。)的活动图表示,在这些状态中,活动状态或BNF声明映射为用例包中的用例。用例包生命周期是用例包行为的准确描述,然而它难以正确表达,尤其在复杂的用例中。用例交互图很容易表达,但它描述的仅仅是由包中用例组成的某一典型场景。
图7是UML活动图,描述了用例包订单管理(order management)的生命周期。在活动图中的活动与图4、5、6中的用例相对应。
注意UML元模型没有定义任何从状态或行为状态到用例实例的映射,这种映射可以在开发过程进行,与Martin和Odell方法相似,其中子系统的每个状态都指明子系统中的一个候选类。参考[5]。然后,其他开发过程可能以其它方式定义用例包生命周期。例如,用例包生命周期的目的在用例包的范围内可被指定为子系统接口操作允许的顺序。
用例交互模型和用例生命周期还有一个显著的区别——它们在项目知识库中的位置不同,并且与其它设计工件的关系不同。工件用例交互模型与工件用例模型相关,工件用例包生命周期与工件用例包相关,后者的抽象级别比相对应的用例模型和用例交互模型高。
符号用UML表示,为了更加清楚,依赖关系用role ends3表示。
在开发流程中,软件构架师、设计者和开发者确认软件产品的某些信息,如用例、软件构架、对象协作和类描述。这些信息可能十分抽象,如产品前景,也可能非常具体,如源代码。在本文中,我们把这些信息叫作软件产品设计工件(design artifacts)。
我们必须认识到设计工件与它的表达之间的区别:设计工件决定业务系统的信息,而表达决定如何把这些信息表示出来。有些设计工件用UML表示,有些用文字或表格表示,例如,类的生命周期可以用UML状态图、活动图、状态转移表或Backus-Naur范式表示。类库用文字来表示。
工作流管理系统的规格说明是定义在精确定义的设计工件基础上的,而不是在图上。这一节和下一节将讨论设计工件的结构,此结构可以明确业务流程、业务规则、软件构架和业务系统设计之间的关系,并且很容易扩展到覆盖业务系统的其他方面,如团队结构和项目计划。
业务系统可被描述为多级的抽象和多种视图。多级的抽象如组织级、系统级、构架级、类级;多种视图如逻辑视图、用例视图、分析视图、测试视图或文档视图。在抽象的每一级和在每一视图里,软件产品可以用四个设计工件来描述:分类器之间的静态关系、分类器之间的动态交互、分类器职责和分类器生命周期。每个工件可用UML图或文字来表示。如图9和图10。
UML分类器是:类、接口、用例、节点、子系统和组件。
分类器模型(classifier model)指定了分类器之间的静态关系。分类器模型可以是一组静态结构图(如果分类器是子系统,类或接口),可以是一组用例图(如果分类器是用例和执行者),可以是一组部署图(如果分类器是节点),还可以是一组组件图(如果分类器是组件)。
分类器交互模型(classifier interaction model)指定了分类器之间的交互。分类器交互模型可以用交互图表示:序列图或协作图。UML表示指南(UML Notation Guide)仅仅描述了那些分类器是对象的交互图,并不描述那些分类器是用例、子系统、节点或组件的交互图。
设计工件叫做分类器(classifier),指定了分类器的职责、角色和分类器接口的静态属性(例如,分类器的操作表,有前置条件和后置条件)。分类器还可以用结构化的文字表示,如CRC卡。
分类器生命周期(classifier lifecycle)指定了分类器状态机和分类器接口的动态属性(例如所允许的有顺序的操作和事件)。分类器生命周期可以用状态图、活动图和状态转移表来表示。
可以把分类器模型的一个实例链接到分类器交互模型的几个实例上,所有这些实例都链接到分类器的实例上,分类器的实例链接到分类器生命周期的实例上。
在结构良好的设计文档中,有关业务流程和软件产品的信息可以很容易定位,并且相关信息链接在一起,同时结构还体现了不同设计工件的完整性和一致性,它是业务专家、顾问和软件开发者沟通的基础。此结构还提供了明显的关注点,由业务人员而不是开发者定义所有的业务规则。这一节讨论业务流程和软件设计工件之间的关系,用它把项目知识库结构化,给出了把业务流程的以及它们与软件设计工件的关系的构造信息。参看[4]获得知识库结构化的具体实例。
结构是基于业务系统中业务对象、角色、工人协作的业务流程(在UML中用用例表示)。业务流程(用例)定义为协作类型,指明了协作职责、目标、前置条件、后置条件和协作中调用的系统操作。业务流程实例(用例实例)为协作实例,指明了在协作中的行为和事件、系统状态和状态转移的具体顺序。
图11指明了业务流程的设计工件和软件系统的逻辑设计之间的关系,工件是按照不同的抽象级别组织起来的:组织级、系统级、构架级和对象级
组织级(organization level)指定了一个组织(如公司、学校和政府机关)的职责,以及该组织的业务环境。工件组织(organization)指定了组织的职责和相关的静态属性。工件组织模型(organization model)指定了组织与其他组织之间的关系。工件组织用例(organization use case)用流程目标、前置条件、后置条件和业务流程必须符合与其相关的静态属性的业务规则来指定组织范围的业务流程。这个业务流程是组织与其他组织之间的协作,这种协作是在工件组织用例模型(organization use model)中指定的,见图11中的依赖关系协作。组织业务流程的实例是由组织交互模型(organization interaction model)用组织与其他组织间的交互来指定的。组织业务流程可以精化到更具体的系统业务流程,见图11中的依赖关系精化。工件组织用例生命周期(organization use case life cycle)指定了所允许的系统业务流程。组织用例交互模型(organization use case interaction model)指定了典型的业务流程实例序列,见图11中的实例依赖关系。组织业务流程的实现用软件系统和它的用户(团队角色)之间的交互来指定,见图11和12中实现依赖关系。
系统级(system level)指定了软件系统的环境以及与它的角色之间的关系。工件系统(system)用职责、前置条件、后置条件、参数和返回值来指明系统的接口和操作。若角色职责和接口是相关的,并由工件角色(actor)指定。系统生命周期(system lifecycle)指定了所允许的系统操作和事件。系统模型(system model)指定了软件系统和角色(其他系统和用户)之间的关系,系统交互模型(system interaction model)指定了软件系统和角色之间的交互。这些交互是系统业务流程的实例,见图11中依赖关系实例。工件系统用例(system use case)用流程的目标、前置条件、后置条件、非功能性需求、业务规则和其他相关静态属性指定了在系统范围内的业务流程。这个业务流程是系统与其它系统或用户的协作。这些系统与它的角色之间的协作是在工件系统用例模型(system use case model)中描述的,见图11中的依赖关系协作。业务流程接口的动态属性,如在业务流程范围内所允许的系统操作顺序,是在系统用例生命周期(system use case life cycle)中指定的。系统用例交互模型(system use case interaction model)指定了典型的业务流程实例的序列。系统业务流程可以精化到子系统业务流程中,见图11中的依赖关系精化。系统业务流程的实现用构架级的子系统间的交互来指定,见图11中的依赖关系实现。
构架级(architectual level)定义了子系统(组件)、子系统的职责、接口、关系和交互。工件子系统(subsystem)职责、前置条件、后置条件、参数和返回值指定了子系统接口和子系统操作。子系统生命周期(subsystem lifecycle)指定了所允许的子系统的操作和事件的顺序。子系统模型(subsystem model)指定了子系统和其他子系统之间的关系,子系统交互模型(subsystem interaction model)指定了子系统之间的交互,这些交互是子系统业务流程的实例,见图11中依赖关系<<实例>>。工件子系统用例(subsystem use case)指定了在子系统范围内的业务流程,这个业务流程是子系统与其它子系统、系统和用户之间的协作。子系统和它的角色之间的所有协作是在系统用例模型(system use case)中描述的,见图11中的依赖关系<<协作>>。子系统业务流程接口的动态特性,如在业务流程范围里所允许的子系统操作顺序是在子系统用例生命周期(subsystem use case life cycle)中指定的。子系统用例交互模型(subsystem use case interaction model)指定了业务流程实例的典型序列。子系统业务流程的实现用类级别上对象之间的交互来描述,见图11中的依赖关系<<实现>>。
对象级(object level)用业务对象、业务对象的职责、关系和交互来描述子系统的设计。业务对象模型(business object model)指定业务对象之间的静态关系。业务对象交互模型(business object interaction model)用业务对象之间的交互指定子系统操作的设计。工件业务对象(business object)指定业务对象的职责和业务对象接口的静态属性,如用前置条件和后置条件描述的接口操作。业务对象生命周期(business object lifecycle)指定了所允许的接口操作顺序。
图12中,设计工件描述了组织团队结构。事实上,它与描述软件子系统结构的工件没有什么太大的区别。团队的角色可以表示成UML构造型的类,工件角色(role)指定工人角色的职责及其它相关的静态属性。工件角色生命周期(role lifecycle)指定了角色的动态属性、它们的状态以及它们所响应的事件。工件角色模型(role model)指定角色之间的静态关系。成员级业务流程(member level business process)指定团队成员角色与其它团队成员角色之间的协作,见图12中的依赖关系<<协作>>。这些业务流程的实例是在工件角色交互模型(role interaction model)用角色实例之间的交互指定的,见图12中的依赖关系<<实例>>。
称为团队(team)的设计工件是一个角色包,指明了团队的职责以及相关的静态属性。团队的动态属性是在工件团队生命周期(team life cycle)中指定的。工件团队模型(team model)指定了团队之间的静态关系。团队级业务流程(team level business process)指定了团队和其它团队之间的协作,见图12中的依赖关系<<协作>>。团队级业务流程的实例是在团队交互模型(team interaction level)中指定的,见图12中的依赖关系<<实例>>。团队级业务流程的实现用团队成员之间的交互以及团队成员与软件系统之间的交互来指定,如图12中的依赖关系<<实现>>。设计工件的模式可以用相似的方法应用在更高的抽象级4上。
这一节描述的设计工件的结构可以通过两种方式简化:
· 只使用设计工件的子集;
· 把紧密相关的一些设计工件结合起来,构成更大的设计工件单元。
使用设计工件的子集不会导致信息的丢失,因为UML图系统不是正交的。意思是同样的信息可以用两个或更多不同的UML图来描述。例如,两个静态结构图和对象协作图描述对象之间的关系。两个状态图和交互图描述对象之间的消息。因为同样的信息可以从几个方位来描述,开发者所提供的仅仅是设计工件的特定子集,否则此工件必须接受关于一致性的检查。
由于实际的原因,设计者可以创建一个更大的可交互工件来包含几个紧密相关的工件。例如,分类器职责和生命周期总是与某一文档相关和结合。也可以把组织、系统、子系统和类用例图结合成一个大用例图,以清晰地区别用例级。同样的,系统、子系统和业务对象静态结构和相对应的所有级别里的交互图可以结合成一个文档,也可用UML语义把静态结构图、组件、节点和每一级的用例图结合起来表示。用这种方法,设计者可以在一个大的静态结构图中表达用例、角色、子系统、业务对象、团队成员和业务流程之间的关系,然而“UML表示法指南”没有清楚地提到这样结合的静态结构图。
本文讨论了用UML表示面向对象工作流管理系统,给出了如何把典型工作流概念映射到UML概念的方法,并建议结构化设计工件,从而跟踪业务流程的定义和面向对象软件设计之间的信息。此结构展示了业务流程可表示为业务对象、团队角色和业务系统中其它实例的协作,此结构基于四种相关的设计工件的模式,这四种设计工件为分类器关系、交互、职责和生命周期。此模式可以应用于一个业务系统的不同抽象级和不同的视图,也可应用于业务和软件系统设计的其它方面。