UML(UnifiedModeling Language)是一种建模语言,更是一种系统分析设计的最佳实践方法。我从2003年开始接触UML,从UML1.1到2.0,感受到了UML的独特魅力,它不仅仅成为在项目和产品分析设计过程中的统一标准,还逐步成为了从需求到测试的最常用公共语言。
我记得在最早接触UML的那段时间,项目组还在辛苦的用着面向结构化的设计思想,写着SRS,画着流程图和数据流图;对OO的设计思想还未真正接触,对于UML只知道系统的设计可以通过9种不同的图来解剖系统,9种图代表了系统的9种纬度,至于如何用到项目中是完全没有概念。
后来,随着Java盛行,OO的思想占据主导,因此接触UML更多了。发觉了解UML越深入就越被其吸引,UML不仅仅是一些图,不仅仅是系统的不同剖面,更是一种业务和系统模型的构造过程。并开始在项目中推动使用UML的标准语言,比如用例图,比如类图。
直到现在,基于UML2.0的应用设计思想仍然是团队中需求、设计、开发人员的主要指导思想。虽然UML1.0的9种图如今扩展到2.0的13种图,然而思想却没有太大变化,在设计中我们依然以用例为驱动,在设计中注重对象的状态变化的分析,注重类的分析和对象间的关系行为分析。
如下图所示,概括了基于UML2.0的APP设计思想。
Ø UML的用法
在我所接触到的项目中,UML是一种设计的指导思想,是一种标准。我经常把UML,CMMI和Prototype合称为项目成功的三驾马车。(现在Agile比较流行,特别是在需求容易变化,项目规模不大的前提下,RUP和Scrum为代表的敏捷方法是可以取代CMMI的一些做法。)
² CMMI负责对项目的各个过程域提供最佳实践方法指导,通过流程、模版和规范来约束和指导操作行为,以减少项目风险和提升项目质量,同时确保组织级的资产成为可持续发展的财富。
² Prototype是对需求过程最好的一种检验,我一直认为需求捕获和分析的能力是项目是否能够交付的最大保障。所以,我迷信通过Prototype来与用户迭代的确认,与开发测试人员按原型来验收成果。
² UML不用多说了,是指导需求,设计和开发过程的一种思想。
另一方面,Martin把UML的用法从深浅分作三个层次:
² 草稿:是最常用的一种方法,主要用于沟通系统的某些层面。如果希望使用的更深入一些,可以通过正向工程和反向工程,实现模型和程序框架的互相推导。
² 蓝图:展现完整的系统设计细节,能够指导开发。与草稿的区别在于,草稿并不是完整,而是注重强调需要交流的重点;而蓝图是完整的,把程序工作变得更简单。草图是探索式的,蓝图是系统性的。
² 程序:以MDA(模型驱动开发)为基础,能够自动从PIM转化为PSM,再从PSM转化为程序代码的过程。
下面谈谈从我的理解如何把UML的思想映射到项目的各个过程中,这些图又如何配合起来使用。
UML2.0包括13种图,其中类图,组件图,合成结构图,部署图,对象图和包图被归于为静态结构图;活动图,用例图,状态机图,时序图,通讯图,交互概览图和时间轴图归属于动态行为图。
在需求分析阶段,可以用到的是用例图,类图,活动图和状态图。
在设计阶段,一般用到类图,时序图,包图,状态图和部署图。
Ø 用例图(use case)
用例图,用来描述人机交互,与系统的互动。是定义和描述需求的最好方法,同时一个好的用例设计,一定是将用例映射到系统实现的类,用例说明了类的迁移和操作。
如下面的用例图所示,
在用例中描述了这些内容:
² 用例的关联角色是:Customer;
² 系统边界是:TeeMall OnlineSystem;
² 基础用例是:Place Order;
² Place Order用例包了(Include)了Supply Customer Data ,Order Product, Arrange Payment用例;
² Request Catalog用例是Place Order用例的扩展(Extend)用例;
² Arrange Payment用例概括了Pay Cash和Arrange Credit两个子用例。
Ø 状态机图(State Machine)
状态机图是类的对象生命周期进行建模。状态机是由状态和迁移构成,是对象局部化视图。
通常,使用状态机图来反映对象状态的变化和其生命周期的模型。比如,以一个信用卡自助电影票购买终端的状态控制机为例。
在一般情况下,终端为空闲状态Idle;
当用户插入卡后,进入买票流程。
状态1:验证。信用卡密码验证,如果验证失败,则购票过程结束,终端退出用户的信用卡,状态变为空闲。
状态2:选择。信用卡密码验证成功后,进入选择状态。选择电影场次和座位,并添加到自己的选择箱中。
状态3:确认。用户选择是否确认选择的电影票,如果选择继续,则返回到状态2;如果选择支付,进入状态4。
状态4:购买。系统完成支付扣账和打印出票,购买过程完成。
特殊操作,在上述四个状态中,都可以进行cancel操作,则进入Idle状态。
如下图所示,
画状态机图有几个需要注意的地方:
² 状态的变迁原因要在图上说明清楚;
² 最好标明清楚状态的开始和结束;
² 不要遗漏任何状态之间的切换。
状态机是一种深度关注细节的图,是观察对象状态变化的紧缩型视图。然而,通过状态机图很难看到全局,系统的整体行为一定是通过多个状态机的结果来决定的,交互视图则正好起到了这个作用。
Ø 活动图(Activity)
活动图用来表示用例的执行流程,一般活动图和状态机图结合使用,很多状态的变迁都是一个活动单元。
很多人将UML的活动图理解成为大家经常使用的业务流程图,特别在活动图中也可以使用泳道,就认为这个和Visio流程图中泳道的意义一样。其实,UML的活动图和一般的流程图最大区别在于,活动图是以OOAD为指导的,是以对象为分析基础,配合状态机图使用,为的是对用例的执行流程进行描述,而并不是以现实中的业务流程为视角。
如下图所示,描述了一个并行的泳道活动图。以订单为核心的对象,并基于订单的几种不同状态进行的流程活动。
角色有:Customer,Sales,Stockroom。
订单状态有:Placed,Entered,Filled,Delivered。
订单活动有:Request Service, Pay, Take Order, Fill Order, Deliver Order, CollectOrder。
Ø 序列图(Sequence Diagram)
序列图用来表示系统内部一群对象之间互传信息的情况,配合用例来使用的话,可以针对每一个用例设计系统内部的一群对象实现用例的运行情况。
对于程序员的编码工作来说,类图和序列图是最值得参考的两款图。
例如下图所示:
Ø 交互概览图(Interaction Overview)
交互概览图是活动图和序列图的混合使用形式,其主要结构像活动图,表示流程,但是参与流程的节点不是一般的动作(action),取而代之的是“交互”(interaction)片段。一个交互片段的内容,正是序列图的一小段交互片段。
对于复杂的对象交互,交互概览图可以用来表示交互片段之间的控制流程,其实可以弥补序列图不易表示控制流程的缺点。不过,换个角度来看,假如序列图复杂到需要搭配交互概览图的话,这张序列图可能就需要拆解成两张图,或者进行重构以降低复杂度。
下图即是一个交互概览图的示例:
Ø 对象图(Object)和类图(Class)
如要搞清楚类,先要明白什么是对象:“带有良好定义的边界、封装了状态和行为的具体实体,就是对象。“,也称作类的实例;类是有相同属性、操作、方法、关系或行为的一组对象的描述符。
类和对象之间的关系就是《instantiate》。比如,
上面图中BankAccount就是一个标准的实体类表示方法,包括了类名,属性(属性类型,多重性,初始值),操作(操作名,参数,返回类型),类范围等。
除了实体类《Entity》外,还有接口类《Boundary》和控制类《Control》。
下图是一个典型的类图,描述了众多类之间的关系。
除此之外,还有多重性,自反关联等多种用法。
Ø 包图(Package)
包是模型元素的容器和物主,每个包都具有自身的命名空间,所有名称必须唯一。
包可以包含用例和类。在设计过程中,一般设计好的包图,都将和程序源代码包目录结构一一对应起来。
如下图所示,就是一个包的关系图,反应包之间,包与边界,包内等关系。
下图是更为详细的类包关系图,反应了包所包含的类,及包之间的依赖关系。
Ø 通讯图(Communication)
通信图跟序列图的功用相似,都是用来表示一群对象互传信息的交互情况。只是,通信图采用网状图形,强调对象之间的链接。而序列图采用栅栏状图形,强调依次发送信息。
Ø 合成结构图(Composite Structure)
组合结构图算也是一种类图,但是它的实用性并不是在一般的业务系统,而是侧重于实时系统或嵌入式系统。类图用来表示系统内部的静态结构,而且它表示的不是系统某一个时刻的静态结构,它表示的是系统在任何时刻下都必须遵守的静态结构。而组合结构图,它表示某一对象的内部结构,其内部由一组小对象组成。这种图有两个特色:其一,它锁定的范围是对象内部,而不是一般业务系统的系统内部;其二,它强调对象内部的组成对象,一般在业务系统中对象是平等的。
Ø 部署图(Deployment)
组件图和部署图都是用来表示实际元素的图,前者表示实际的软件程序,后者表示实际的硬件设备。实际上,部署图最常用来表示系统的硬件设备及架构。如下图所示:
Ø 组件图(Component)
组件图表示系统的组成组件(component)、组件所提供的接口(interface)或者是所需要的接口,以及组件之间的依赖关系。组件指一个具体的模块单元(modular unit),但是必须具备定义明确的接口(well-definedinterface),并且易于替换(replaceable)。如下图所示:
Ø 时间图(Timing)
前面提到的状态图用来表示对象因为事件的触发而转换状态,所以它着重于事件与状态的关系。而时间图也是在表示状态变化,但是它着重于状态与时间的关系,用来表示对象在某一状态停留了多久的时间后,将转换到下一个状态。时间图很像心电图,通过高高低低的曲线来强调状态的变化。如下图所示:
本文参考了:
《UML精粹:UML Distilled Third Edition》
ByMatin Fowler
《The Unified ModelingLanguage Reference Manual》
By Jacobson,Booch, Rumbaugh
《UML 2.0 and UnifiedProcess》
By Jim Arlow, Ila Neustadt