OO系统设计师之路--分析模型系列(2)--怎样做分析模型
分析模型是系统的高层抽象,是高于实现语言和实现方式的。因此在做分析模型过程中,要跳出固有的java思维,C++思维,同时也暂时不要考虑设计模式的应用,而专心的,用OO思维把四个分析类的职责和交互,以及它们之间的关系定义清楚。如果说用例分析大部分情况下是程式化的(笔者正希望它是程式化的),那么你会发现,分析模型大部分工作也是程式化的。
拖了很长时间才写第二篇,为自己的懒惰羞愧一个:P
上一篇笔者阐述了什么是分析模型,我们为什么要使用分析模型,分析模型能给我们带来什么。这一篇来讨论怎么做分析模型。
开篇之前先说点题外话。笔者不厌其烦地一次次提到需求的可追溯性,是因为软件工程比UML更重要更本质。笔者自己在学习UML过程中,曾经也非常迷惑而不得要领,这么多UML元素,每个都有其特定的含义,RUP中定义了更多更复杂的流程,模板,工具...虽然读了很多资料,却始终感觉UML信息太过于分散,不能很好的把UML应用到实际的项目中去。直到有一天突然转变了思维,不是从UML的定义中去思考如何做软件,而是站在软件工程的角度,去UML中找寻需要的工具。正是这一转变使我对UML的认识茅塞顿开。我想,初始学习UML的人可能也会经历跟我同样的困惑,在这里我愿意把我的领悟与大家分享。对软件项目来说,OO也好,面向过程也好,UML也好,UC矩阵也好,这些都不是最重要的,软件项目真正的灵魂是软件工程。软件工程的需要才是这些工具诞生的原因。因此我建议阅读我文章的朋友们,在讨论如何应用UML之前,应当先系统学习软件工程。只有掌握了软件工程,你才会知道为什么要有用例,为什么要有分析模型。站在软件工程的立场,那些孤独的UML图符才会变得有生命力,你随时都会知道需要用什么样的UML图符来表达软件的观点。UML也不再面目可憎,它们是一群有着强大能力的精灵,帮助你在复杂的软件工程道路上搭起一座座通向光明目标的桥梁。
虽然是不厌其烦,还是要再次提醒,注意需求的过追溯性,这是软件工程的需要。这一篇我们要讨论的话题里,仍然逃不开这条主线的牵引,你会发现这一篇里产生的任何一个成果都与之前的工作息息相关。如何做分析模型?在UML里,RUP里没有明确的答案,我从软件工程中找到了答案,正如上一篇所说,析模型是采用分析类,在系统架构和框架的约束下,来实现用例场景的产物。用例场景是什么?是用户需求的模拟,实现用例场景,就是实现需求。为了达到需求可追溯的目的,分析模型需要以下这些输入(还是采用用例分析系列文章中的例子):
- 用例场景
- 与用例实现相关的领域模型
- 用例规约 以及
- 补充规约
在正式开始做分析模型之前,笔者有必要提醒一下,分析模型是系统的高层抽象,是高于实现语言和实现方式的。因此在做分析模型过程中,要跳出固有的java思维,C++思维,同时也暂时不要考虑设计模式的应用,而专心的,用OO思维把四个分析类的职责和交互,以及它们之间的关系定义清楚。如果说用例分析大部分情况下是程式化的(笔者正希望它是程式化的),那么你会发现,分析模型大部分工作也是程式化的。let's begin!
现在,我们有这样一些原料,用例场景提供了需求的输入,领域模型提供了初始的业务原材料,还有用例规约和补充规约提供了详尽的规则。正如笔者在之前的文章中提到的一句话:用例场景非常非常的重要,后续的工作就靠它了。这句话开始起作用,我们的第一步,就从用例场景开始。
做分析模型的建筑材料就是四个分析类,我们要用它们来搭建用例场景。actor分析类来自用例分析中的actor,实体类来自领域模型,边界类来自用例场景中actor-计算机交互,控制类来自业务规则(包括用例规约中的前置、后置条件、业务规则以及补充规约中的全局规则)。所使用的工具是时序图,目标是实现用例场景。我们先来做一个草图,对照着用例场景图,一步步来,得到这个结果:
- 分析模型草图(图片比较大,由于Blog框架的问题,如果看不全,可以在图上右键->图片另存为,保存到本机再看)
我们来分析一下上面的草图。首先,这幅草图大家可以看到,所有的实体类没有做任何变动,直接照搬了业务实体(领域模型),所谓的控制类,只是机械的在每一个实体前加了一个控制器,边界类只用了一个。至于过程,更是和用例场景一模一样,只不过形式不同而已,改用了计算机术语。这个例子只有一个用例场景,如果有多个,每个场景画一次,重复用到的类直接拖过去,能用的方法直接用,还没有的就加上,总之忠实的实现这些用例场景就好了。整个过程很简单,很程式化,对吗?不用脑子都能做。尽管如此,我们仍然得到了一个分析模型的静态图,就象下面这样:
小提示:在做分析模型时,从时序图开始做,需要用到一个分析类时,就转到类图中创建这个类,再从左边的树形列表里把类拖到时序图上。从一个对象画一条表示交互消息的箭头到另一个对象后,右键点击线条,选择"new operation",再输入操作名,这时Rose会在线上标明这个操作名称的同时在对应的类上创建这个方法。这样,在绘制时序图的同时也生成了静态类图。最后再把类之间的交互用线连起来表示这个关联关系,静态图就完成了。
- 分析模型静态图
再来一个小提示:rose对中文的支持不好,因此上面的图中类下面无法完整的显示用中文写的方法名,不过双击open sepcification对话框能正确显示。相信大家注意到我所有贴上来的图文字都是仿宋体而不是通常用的宋体,这是因为在字符集里,宋体并没有被限定为GB2312,所以当把rose里的图全选并拷贝到画图或WORD里时会文字会变成乱码。大家一定也遇到过这种情况吧?一个小技巧就是用仿宋字体,预先设定字体或者全选(crtl+A会吧),再菜单format->font,选仿宋,你可以看到在仿宋字体后面带了GB2312的字样^_^。这样就不用先屏拷再剪切,再拷贝到word里了。用word2003的朋友幸运了,没有这个问题。
不可否认,这个类图很粗糙,但是一个系统原型已经出来了。我们得到了可以完全实现需求的一些类,主要的类方法也有了。如果你想偷懒的话,直接把它转换成设计类图,把中文方法名改为英文,再把领域模型文档(不记得了回头查以前的文章)中提到的实体属性填入,就已经可以交付开发了。因为需求已经实现了,类有了,方法有了,类属性有了,别忘了在用例分析过程中已经用静态HTML做了系统原型,因此界面也有了。一切开发需要的东西都全了。比如我们用Strus+hibernate架构,一个实体类就是一个POJO,一个控制类就是一个action,至于界面,在静态HTML里填入java代码改成JSP呗。如果你是一个开发人员,把这个图给你,相信你也会觉得开发这个需求是很明确很简单的事吧?呵呵,成就真不小,可是仔细想想,我们甚至都没有动脑子啊!真是的,我们没有动脑子,居然就做了一个设计,恩!?可事实就是这样,谁说分析设计就一定要动脑子?不动脑子就不能做设计吗?就不能体现一个设计师的价值吗?设计的目的是什么?漂亮?好看?采用了很多新技术?体现了设计师的高明手段和渊博知识?NONONO!设计的目的是为了实现需求不是吗?如果需求就是这样简单,我们已经实现了,还能不动脑子,干嘛做那没事找抽型的,老板又不因此少付一分钱工资,能少干点活儿不好吗?很多设计师因为懂得几个设计模式,总要想方设法弄上去,把简单的问题弄复杂,好象只有这样才能体现他的价值。爱因斯坦说宇宙的法则是简洁的才是最美的,设计也是如此。设计师的真正价值,是用最简单,最好懂,最简洁的设计完成最复杂的要求,而不是相反!一项技术,正因为能够被大多数人掌握才能流行,否则就只能呆在实验室里,不是吗?
话扯远了,忍不住又抨击了一下过度设计,很不幸被抨击的对象也包括以前的自己^_^。好吧好吧,我知道尽管你会同意我的话,你还是会在心里嘀咕,如果设计就只有这一点东西,连脑子都不用动,那设计师也太好干了吧?分析模型如果就只有这一点内容,还要专门写个系列文章,这个作者也是个欺世盗名的吧?
呵呵,为了抚平你的失望,我告诉你。之所以我们没动脑子,是因为系统分析员们经过用例分析系列中的卓越工作,给我们打下了如此坚实的基础,才使得我们的工作简单到了不用动脑子的地步。你还得感谢UML用一套很好的方法,让你可以轻而易举的从需求转化到类设计。你已经站在巨人的肩膀上了,所以就一边儿偷着乐吧。
乐完了还得回到现实。在很多情况下,事情并没有这么简单。这个粗糙的分析模型虽然可以工作,但的确有很多可以优化的地方。不用担心你会因为做了一份简单而不用动脑子的工作而失去饭碗。因为下一篇,我们将会讨论怎么样,从哪些方面,以及如何依据补充规约,系统架构以及维护要求等来优化和调整这个模型。这下设计师有用武之地了,学习到的知识和积累的经验要发挥作用了,失落的自我价值也能体现了。为了证明设计师不是混吃喝的并且保住饭碗,敬请期待下篇,分析模型的优化和调整。