|
经常听一些初学UML的程序员反映UML太复杂,很难学。回想起自己几年前刚学UML时,也是久久不得入门。细想一下,也许初学者之所以觉得UML复杂,是如下两个原因: 1)不知觉中总是以程序员的角度来理解UML。其实,UML首先是一个分析工具,其次才是一个程序设计的工具。我认为,比之程序设计,UML在业务分析和需求分析过程中发挥的作用更大,而且,只有使用UML作需求分析之后,UML才能较好的在后续的软件内部设计中发挥作用。如果一上来就试图以UML作软件设计,往往会因问题过于复杂而作罢----或者无从下手,或者过早陷入细节。 2)UML标准设计是要解决各种类型的软件的各个开发阶段的问题,而我们每个程序员面对的具体软件项目,往往没那么复杂,只需要用到UML中极少一部份功能,因而感觉UML太复杂。UML既要解决嵌入式软件的开发问题,又要解决像B/S那样的信息系统的问题,还要像Photoshop之类功能繁多算法和操作复杂的软件问题。此外,在软件开发的各阶段----业务分析,需求分析,架构设计,详细设计----面对的问题各不一样。因为UML面对的问题领域广泛而复杂,因而UML本身确实有一定的复杂性。不过就每一个具体项目而言,我认为,大多数项目用到的功能不会超过UML所有功能的20%。 基于第二点,我们只要学会UML中最有用的部分即可,基于第一点,我们首先要转换自己的思维习惯,先分析问题,而后再考虑解决问题(程序设计)。 UML中最有用的部分是什么呢?这个问题可以分解为两个小问题,一是UML的这么多图里头,哪个最重要,二是对每一种图,语法很多,哪些语法最重要,或者说每种图的关键点是什么。很多初学者觉得序列图最有用,这是程序员的思维方法,因为序列图和函数调用很像,所以程序员往往最喜欢序列图。其实序列图恐怕是UML中应用范围最窄的图了,它几乎只能用于软件设计阶段,分析阶段几乎用不上。我认为,UML中各个图的有用顺序是(高低):状态图/活动图-->Class图-->协作图/序列图-->用例图-->Deployment/Component图。 理解状态图的关键点是什么呢?首先考虑一下我们面对的问题是不是有多个状态,而且状态间的切换比较复杂。譬如说开发一个Bug管理系统,显然Bug有如下一些状态:open, assigned, fixed, validated, close ,这些状态间的转换需要相关操作人员作一定的动作,而且,这些状态间并不是顺序转换,例如由Validated可以再次转到assigned状态。其次,考虑一下,待分析问题的各状态间转换需要什么条件和动作。状态不会随便转换,必须有一定的事件或者动作发生状态才会变化。状态图用于建模待分析问题的状态和状态转换时的条件/动作。怎么画状态图呢?对于初学者,我建议先用文字描述问题的各个状态,以及状态间的转换(源状态目标状态,条件和动作)。如果不能用文字清楚描述待分析问题的状态变化,那就不可能画出状态图。当用文字描述的时候,会发现文字描述冗长而又难于理解,这时可以考虑用状态图来建模问题了。画图时不必过于在乎UML语法,只要用方框表示状态,用带箭头的线表示转换即可。例如上述Bug的状态图:
开发组长 开发人员 测试人员 测试组长 分配Bug 修改Bug 确认Bug 关闭Bug Open-------->assigned------->fixed------->validated-------->Close ^ | | | ----------------------
画好图以后,往往还要补充文字,对各状态的含义以及部分复杂的转换进行说明。单有状态图,能使人一眼就明白问题的全体,但在复杂情况下,每一状态和转换的详细含义在图上难于描画,因而往往还要配以文字说明。 抽象的讲,只要待分析问题有多个状态,那么就可以用状态图来建模问题。不过具体到软件项目开发中,该怎么使用状态图呢?这往往也是初学者很困惑的问题。在业务分析和需求分析阶段,状态图经常用于描述业务对象的生命周期,在程序设计阶段,状态图经常用于刻画程序对象的生命周期或状态变化。例如前述的Bug状态图就是需求分析阶段的图,它通常出现在需求文档中。随着软件项目的进展,需求阶段的状态图会演化成软件设计阶段的状态图。这个演化不一定是一对一的演化,需求阶段的状态图到了设计阶段可能变成若干张图,也可能没有了。例如上述Bug管理系统,在分析阶段,Bug是个业务对象,到了设计阶段,Bug多半会变成一个程序对象,即需要编程实现的一个Class。在设计阶段,当我们详细设计Bug类时,可能会再次用到状态图来说明Bug对象的状态变化。这时的状态图和分析阶段不一样,状态变成了Class的属性值,状态变化变成了属性值的修改,状态改变动作变成了类的方法调用。如下图所示(该图通常出现在设计文档中):
Call Call Call Call Assign() Fix() Validate(true) Close() status=1--------->status=2------->status=3----------->status=4-------->status=5 ^ | | Call Validate(false) | -------------------------------------
只有开发组长才可以Assign Bug,只有Bug担当者才可以Fix Bug,象这样的业务规则,可以分别落实到Assign()和Fix()方法中实现。 当然,并不是一定要用状态图来设计Bug类,用不用完全取决于是否有助于说明问题和简化问题。只有能使问题更清晰更简单时才用状态图。而且往往是有分析阶段的状态图,才会有设计阶段的状态图。如果一上来就直接画设计图,那问题就会很复杂,你的设计图的依据是什么?软件的使用者(客户)不明白设计图,但他们明白分析图。前述的分析阶段的Bug变化图才是客户头脑中想象的东西,只有先画出分析图,找客户确认。之后再以分析图为根据,画出设计图。软件实现者(编程人员)明白设计图,他们头脑里天天想的是Class,属性和方法。 (今天先说到这里,下班了,如果于各位读者有益的话,以后再说其他的图)
|
一共有 28 条评论