UML是什么
UML的概念包括了UML语义(Semantics)和UML表示符(Notation)两个部分,UML语义定义了结构(Structural)模型和行为(Behavioral)模型。结构模型(又称为静态模型)强调系统的对象结构,如对象的类(Classes)、接口(Interfaces)、属性(Attributes)和关系(Relations);行为模型(动态模型)关注的是系统对象的行为动作,如对象的方法(Methods)、交互(Interactions)、协作(Collaborations)和状态(State Histories)。以此为基础,UML为UML表示符提供了完整的语义定义。UML的表示符包括了下面的几种主要的图:类图(Class Diagram),用例图(Use Case Diagram),顺序图(Sequence Diagram),协作图(Collaboration Diagram),状态图(State Diagram),活动图(Activity Diagram),部署图(Deployment Diagram)语义由于我们的讨论重点并不是UML语言,我们只是简单的介绍UML的实际应用,如果大家对UML有兴趣,可以参看《UML1.3白皮书》。
4. 用例图和用例
用例图(Use Case Diagram)是UML中最简单也是最复杂的一种图。说它简单,是因为采用了面向对象的思想,又是基于用户视角的,绘制非常容易,简单的图形表示让人一看就懂。说它复杂是因为用例图往往不容易控制,要么过于复杂,要么过于简单。一个系统的用例图太泛不行,太精不行,太多不行,太少也不行。用例的控制可以算是一门艺术。突然想起当年我刚刚接触UML的时候,对用例不屑一顾,认为是UML中最无用的一种图,现在每每想到不禁感慨自己的愚蠢。
Use case diagrams show actors and use cases together with their relationships.『OMG-UML V1.3』
用例图表示了角色和用例以及它们之间的关系。
A use case is a kind of classifier representing a coherent unit of functionality provided by a system, a subsystem, or a class as manifested by sequences of messages exchanged among the system and one or more outside interactors (called actors) together with actions performed by the system. 『OMG-UML V1.3』
用例描述了系统,子系统和类的一致的功能集合,表现为系统和一个或多个外部交互者(角色)的消息交互动作序列。
有点复杂是吗,就是角色(用户或外部系统)和系统(要设计的系统)的一个交互,为了实现一个目的(Goal),这个目的的描述通常是一个谓词短语,例如,开立信用证,给客户回单等。用例图则图形化的表示了这种关系。
一个具体的用例图可能是这样的:
5. 用例和需求,用例和过程
可以说,之前说的所有的东西都是为了能够导出用例在需求中的作用。用例是从用户的角度看待系统,而不是基于程序员的角度。这样的话,用例驱动的系统能够真正做到以用户为中心,用户的任何需求都能够在系统开发链中完整的体现。用户和程序员间通过用例沟通,避免了牛头马嘴的尴尬局面。
从前,系统开发者总是通过情节来获取需求,是问用户希望系统为他做什么。在可爱的Jacobson发明了用例的概念之后,需求获取就变成问用户要利用系统做什么。这是立场不同导致的结果。用户通常并不关心系统是如何实现的(也有少数可爱的技术狂是例外)。对他们来说,更重要的是要达到他的目的。相反的,大部分的程序员的工作习惯就是考虑计算机应该如何实现用户的要求。所幸的是,用例方法能够调和双方的矛盾,因为虽然用例是来源于用户,服务于用户,但是它同样可以用于开发的流程。当系统的开发过程都是基于用例的,用用例获取需求,用用例设计,用用例编码,用用例测试的时候。这个开发过程就是用例驱动的。
在具体的需求过程中,有大的用例(业务用例),也有小的用例。主要是由于用例的范围决定的。用例像是一个黑盒,它没有包括任何和实现有关或是内部的一些信息。它很容易就被用户(也包括开发者)所理解(简单的谓词短语)。如果用例不足以表达足够的信息来支持系统的开发,就有必要把用例黑盒打开,审视其内部的结构,找出黑盒内部的Actor和Use Case。就这样通过不断的打开黑盒,分析黑盒,再打开新的黑盒。直到整个系统可以被清晰的了解为止。
用例是重要的,用例图只是用例的表达方式,其实用例的表达不仅仅是用例图,还有很多方式,我们在下面会具体讲到。
6. 使用用例的误区
上面曾经花了一些篇幅来说明用例的简单和复杂的关系。在很多介绍UML的书中都会首先介绍用例图,并会用一些近乎完美的例子来说明用例图。可是在实际的使用过程中,都会有很多实际的问题。我咨询过很多使用UML的朋友,发现或多或少都存在问题。
用例的发明者Ivar Jacobson 曾经说过,Ericsson花掉了上千万元去研究建立Use Case模式的过程(process) ﹐现在他任职的Rational公司也花掉不少钱研究开发过程的问题。大师花了数十年心血建立起来的理论体系并不是那么容易的。用例决不仅仅是定义Actor、Use Case、Association那么简单。用例需要在很多的细节方面都做足功夫。我曾经看过一个软件企业推行Use Case图,但是在花费心血画出了几十张项目的用例图后,设计编码阶段却回到了从前的开发流程。
用例的使用绝不仅仅是画用例图,用例也不是软件团体一步登天的捷径。用例贵在思想,在软件团体中引入用例并能够和团体很好的融合,是一个渐进的过程。因为在软件工程领域应用用例思想涉及到的内容方方面面。即使是用例图的编号也是大有讲究。对于一个没有OO实践经验的软件团体,从事这样的作业,需要大量的工作,可以说是"百业待举"。如果没有长期的积累和探索,何来用例和软件团体的融合呢?
7. 用例的观点
为什么说用例是有效的呢?在软件开发的过程中,大部分问题的产生都是由于沟通的不畅。设计者和用户沟通不畅,设计者和实现者的沟通不畅。软件开发就是踢足球。教练、前锋、中场、后卫各顾各的,相互之间形成断层,怎么能赢球呢?上面提到的一些应用OO用例思想失败的例子也表明,如果开发团队有人排斥用例思想的话,项目是不会成功的。
用过Rose的人都知道,在Rose的界面中,有四种视图(View):用例视图(Use Case View),逻辑视图(Logical View),组件视图(Component View),部署视图(Deployment View)。这个思路源于Kruchten大师提出来的4+1的观点模式。其描述了系统开发工作的参与者﹕使用者(end users) 、程序员(programmers) 、系统整合师(system integrators)、以及系统工程师(system engineers)等5 种人员心中所关切的焦点与看法。
为了能够把4种人不同的观点统一起来,Kruchten大师提出了一个情节(Scenarios)观点(这个词翻译的不好,如果有谁有更好的翻译,请更正)。这个观点其实就是用例观点(Use Case View)。在用例观点的统一下,保证这四种观点能够相互协作,共同营造一种良好的开发氛围,实现软件项目的成功。
那么,应该如何营造一种和谐的气氛呢?还记得在介绍UML语言的时候我们谈过UML中的几种图吗。这几种图都不是孤立的。在画出一份用例图后,通常都会用顺序图和状态图来规定用例图的规格,这些都是Rose中的用例视图。在用例图中,我们可以分析出基本的类,并将类组织成包,并将其分配到系统的三层结构中,这是Rose中的逻辑视图。在写出基本类之后,我们还可以将类组织成组件(针对特定的架构,如J2EE或COM),这是Rose中的组件视图。把组件部署实现,就是Rose中的部署视图所关心的。(需要指出的是,Rose中的视图与Kruchten大师的4+1观点有些许出入,Rose中的组件视图相当于Kruchten大师的Development观点和Process观点。)
(注:这里的View对应的有两种说法:视图和观点。视图是比较正式的说法,但是我觉得在通常得用语中,大多采用观点的说法。所以这里的观点和视图表述的是同一个意思。)
这里谈到用例的观点主要是要让大家了解为什么会有用例的产生,以及在软件开发中不同的人看待问题有不同的角度。
8. 用例的不足
用例的出现虽然能够解决很大一部分问题,但是它并不是万能的。
The first is the matter of how difficult it is to get a UML-like design into a state that it can be handed over to programmers. The problem with a UML-like design is that it can look very good on paper, yet be seriously flawed when you actually have to program the thing。(Fowler 2001)
首先是把像UML那样的设计图交给程序员来实现是一件极为困难的事情。问题的关键在于那种设计看上去不错,可你打算编程来实现它的时候就出现了问题。
不但是分析员和程序员之间的沟通存在问题,客户和分析员之间的隔阂更大。客户对于用例的观点仍然不能够接受,这仍然需要开发人员作出不懈的努力来调和这一矛盾。
由于软件工程最早提出是根据建筑方面的理论,所以很自然的就会把软件工程和土木工程做一个比较。在土木工程中,设计图和模型制定出来来需要严格的执行。可是:
The models that civil engineers use are based on many years of practice that are enshrined in engineering codes. Furthermore the key issues, such as the way forces play in the design, are amenable to mathematical analysis. The only checking we can do of UML-like diagrams is peer review. (Fowler 2001)
土木工程师使用的模型建立在多年实践的基础上,它们用土木工程的专用语言来描述。而且主要的问题在于,通常这种设计需要符合数学原理。而我们对UML之类的图表唯一能做的就是同级检查。
看到问题所在了吧。单纯的凭借没有完善理论支撑的设计图就轻率的决定这个软件的设计是及其危险的。不止一次的经验告诉我,一开始写出的用例在项目结束时一看往往会吓一大跳:设计和实现已经完全脱节了。其中主要的代沟有两个:客户和开发人员之间,分析员和程序员之间。我们这里的重点在于客户和开发人员之间的需求部分。
需求的问题单单由UML语言来解决是不现实的,且不说国外的软件环境那么好的情况下,客户对于UML仍然不理解。国内的情况要糟糕的多,大多数的客户并没有计算机方面的基础知识,对于他们来说,只有一点:"花钱买东西,天经地义。"在这样的观点下,软件的开发过程就很难得到客户的支持。所以这也是国内ERP项目鲜有成功范例的一个重要原因。
这时候,讨论的问题已经不是局限在技术层面了,主要的焦点已经转移到了管理、营销、谈判技巧等方面了。UML的成功也是需要这个大前提在的。McConnell建议在一个大的项目中,编码和单元测试的开销占整个项目开销的15%。而其中有很大一部分的时间都会花在BPA(企业流程分析)和BPR(企业流程再造)上面。因为有很多企业在实施电子化之前管理都不规范,以人治为主。对于软件而言,不论其中的设计多么的成功,如果没有各个环节输入的准确来保证,那结果是可想而知的。我的一个朋友开发过一套连锁店管理的软件,可是系统运行以来,会计帐从未平过。其中主要的问题就是各个结点的输入不规范。这种问题已经不是计算机能够解决的了。说到这里,有一个笑话,有一个特定行业的企业要开发一个管理软件,于是我就给企业的负责人分析他的流程,突然他很惊讶的看着我:"你是我们这个行业的吗,怎么比我还熟。"其实,我只是以逻辑的观点来分析他们流程,把一些漏洞给堵住。关于业务建模方面的知识,在接下去的文章中还会有大规模的篇幅,这里就不罗嗦了。
所以呢,作需求分析,往往技术并不是最重要的。
9. 迭代式的需求分析
软件工程不断的向前发展,其中的一些新兴的方法论中的佼佼者就是XP。(关于XP的介绍请参看我的上一篇文章)。XP对需求的影响在于:开发方和客户方已经不再是客户关系,而是战略合作关系。客户将作为领域专家参加整个开发过程,并提供现场(on-site)指导。
XP大概的流程是:领域专家组(包括开发方和客户方)将会提出需要开发的功能,体现为素材卡片(Story Card)。项目经理配合将素材卡片分配到每个迭代周期。各个素材卡片都会有一个小型的开发团队(由分析人员、开发人员、品保人员组成)来负责。每次迭代周期都会得到一个可发布、可供客户使用的产品。通过把整个项目划分为多个迭代周期,可以:
不可否认,XP作为新生代的方法,有它的优势所在。可是要指出的是,在中国,能够采用XP方法企业可以说是屈指可数。这个问题大家经常都可以看到评论,这里就不罗嗦了。不过,有一种开发环境,还是有天然的使用XP方法的优势的。就是内部开发。例如很多的大型企业、银行、事业单位都有自己的软件开发部门。这种和客户关系特别亲密,使用XP方法就有他的优势。只是,目前影响这种开发方式的主要原因,却是在体制上的。
10. 小节
平心而论,UML还是不错的,绝对值得我们花时间来学习。尤其是随着大环境的逐步改善,UML将很有可能成为统一建模语言,就像它的名称那样。需求要是Customer Oriented的,这点知易行难。要采用先进的方法,更非朝夕之功。