对象建模技术

连载:对象建模起步之五 健壮性分析

    今天向大家介绍ICONIX建模方法中的重要内容:健壮性分析。通过上两次连载中介绍的工作,我们已经有了一个成型的层次类模型,这是基于对需求的分析获得的一个整体概念。到目前为止,我们所做的工作目的是了解这个系统,即所谓分析阶段,那么如何从分析阶段过渡到设计阶段呢?健壮性分析登场了,这是一门十分简单但非常有效的技术,通过简单的30分钟学习大多数设计师都能很快地掌握。

    健壮性分析不是UML固有的一部分,它包含在“Rational的UML特殊对象过程扩展”中,也不是正规的OO设计方法,因此大多数的UML书籍中根本没有提到它(现在你有福了,本篇文章将详细介绍这项技术,为此我还专门去找了一些参考资料来,以免说错了闹笑话)。

    健壮性分析是将参与用例中的对象集(层次类模型也是脱胎于用例的)进行归类,然后分析对象间关系的方法。和MVC有点类似,健壮性分析将对象(这里不称为类,因为属于动态分析,参与者都是类的实例)分成三类:

  1. 边界对象,参与者使用该对象与系统进行交流
  2. 实体对象,这个不用多说了吧
  3. 控制对象,边界对象和实体对象之间的桥梁

    有四个规则对应三类对象间的交互:

  1. 用例的动作者(那个小人)只能与边界对象交互(结构化分析里面的自动化边界)
  2. 边界对象只能与控制对象和动作者交互(即不能直接访问实体对象)
  3. 实体对象只能与控制对象交互
  4. 控制对象可以和边界对象交互,也可以和实体交互,但是不能和动作者交互

    好了,让我们启动Rose,做个图给大家加强认识

   健壮性图分析规则

    通过绘制健壮性分析,可以很容易的获得几个关键性的内容

  • 正常性
  • 完整性
  • 再发现对象
  • 初步设计

    下面是我对猜数游戏建立的健壮性分析图:

    通过对健壮性分析图的分析,可以做出一次游戏交互的顺序图:

    最后,健壮性分析是一个工具,用完了以后无需保留它,它在以后的设计中并没有多大用处。

 


 

连载:对象建模起步之六 完善设计

    原本连载准备写到10篇左右,可是讲完了健壮性分析以后就没有多少理论可讲了,剩下都是一些技巧性的工作,前面已经说过这个连载不讲述UML,如果读者需要获得UML方面的知识可以参考其它资料。我在这一篇把剩下来的部分做个大略介绍,这个连载就此告一段落了。这里没有介绍用例建模方面的内容,大半原因是这方面自成体系,以后有空我会陆续向大家介绍。

    模型的初步设计在完成健壮性分析以后已经完成,设计者手中已经有了一个初步的类体系,如果读者有UML基础,很容易利用UML所提供的各种工具来完善设计。

    如果发现所拥有的类图不完整,应该继续使用健壮性分析来研究它,持续发现类,直到整个体系完整。

    在类图已经完整地情况下,应该为类分配方法和属性了,这是设计的关键一步。由于我们使用了快速原型法,在很多地方可以使用逆向工程来减轻工作量(边界类)。控制器和实体的属性(Attribute)与行为(Method),则可以通过顺序图来分析,如果读者熟悉CRC卡片,那也是获得行为的好方法。

    顺序图可以直接转换成协作图,我个人通常不怎么使用协作图,但是如果它对你有用,也是不错的。在Rose里面只需要按一下F5键就可以从顺序图得到协作图。

    在为每个类分配完方法和属性后,就是考虑如何实现的问题了,建模的工作已经完成。

    其实建模没什么难的,只要记住时时检查需求,不要让设计失控就行,你一定会成功的。

    对象建模起步连载完。(有点虎头蛇尾,没办法了,后面的部分跟建模方法基本没什么相关,全是如何画图方面的技巧,我即使写一大堆也不够市面上那些书写的好)

    多谢大家的支持,向所有支持我的朋友表示感谢。

 


 

连载:对象建模起步之四 域建模之二 分析层次类

  在上一次连载中,我们已经初步对问题域进行了分析,获得一个类名的列表,接下来的工作则是绘制这个分析层次类。很显然的,拿到类的列表,当然应该做Class Dragram,这里也不需要使用特定的工具,任何矢量绘图工具都可以完成这个工作。请大家注意,这个阶段制作的类图,并不是最终要实现的类图,而是一个分析类图,它的功能是帮助设计师理清系统的关系,将需求文稿中错综复杂的关系整理成一个脉络清晰的完整系统。

  请原谅我上一章使用了一个不太恰当的例子,这个游戏过于简单,只有一个参与者,只有一种活动,要是画用例的话就只有孤零零的一个圈圈加一个小人。我在这里列出的问题纯粹是为了阐述分析思路而提出问题,大家日后做项目的时候千万不要像我这么故意把事情搞复杂。
  闲话少说,先启动ROSE制作Class Dragram,一开始应该是这个样子的

  现在我们要用我们的专业知识来归纳类了。很明显,错误信息和成功信息需要一个基类,玩家答案和正确答案也是一样。于是,类图变成了这个样子:

  请大家再次原谅我故意把系统搞得这么复杂,其实对于这个简单案例来说根本没有必要做这种工作,我只是要说明在发现类以后应该要对类进行归纳处理工作。实际项目中的类一定是非常多的,分析它们之间的关系十分重要,这是让设计师能够把握全局的重要方法。

  接下来则是分析类之间的关联,同样从需求文档和问题域中寻找线索。

  “游戏引擎应该准备一个正确答案”,没错,游戏引擎肯定要用到正确答案的。

  做到现在问题来了,很明显这个游戏的核心其实就是一个比较操作,那么这个操作应该放到哪里去处理呢?(噢,其实这不应该是在这时候考虑的事,但是由于项目比较简单,我也就不亦步亦趋的照着顺序来了)。不知道读者知不知道MVC?也许有人搞过,但是是否知道MVC的分析方法?如果知道看后面的内容十分容易,如果不知道就要仔细看后两章的内容了。其实在OO设计中一早就有和MVC类似的东西,那就是健壮性分析,和MVC类似,层次类也有三个归类:边界、实体、控制器。现在我把类做一个简单分类:

  这里只有实体和边界类,还没有控制器,所以我需要引入一些Helper类来补充这个层次类图,不过今天到此为止,手累了。

  另外,从本章开始起,我这个连载的题目要改一改,由于现在和以后将要加入其他技术,同时也会裁剪掉一些ICONIX的内容,不能再叫ICONIX了,以免真正搞ICONIX的人来找我麻烦,直接叫对象建模好了。

 


 

 

模型、UML、快速原型和ICONIX

    废话不多说,要想搞RUP也好ICONIX也好,需要对模型、UML有个大致的了解。什么是模型呢?说穿了就是对具体事物的抽象。比如你去买楼,不管售楼小姐给你说的如何天花乱坠,在没有看过现楼之前你心里还是没谱,只有你亲自到了房子里面看过,你才知道到底是个什么样子。可是你没有那么多时间,还有可能开发商根本还没有盖好这个房子,这时候售楼小姐就会带你到沙盘面前,指着一个房屋模型说:这就是你要买的房子。

    好了,虽然现在你没有去看过现楼,不过看到这个模型,应该对要买的楼也有了一个大概的认识,抛开奸商骗人的因素以外,以后你看到的现楼根眼前这个模型在结构上是一样的。当然房屋模型并不能表现出所有的特征,比如自来水管的走向和电灯开关在哪,虽然这些因素对居住品质的影响也很大,但是这并不是你买楼时首要的考虑。同时开发商一般会准备多种模型可供你参观,比如小区的整体模型和房型模型,透过小区模型你可以看到你要买的房子在小区的哪个部分,周围绿化情况,交通之类的大致情况,而透过房型模型可以看出房间布局、客厅大小等等相对具体的情况。当你看完所有的模型后,基本上心里也有了底,大部分的人也就依据这个情况决定是否购买这套房子。

    类比房屋模型,软件模型(一般我们称系统模型)所起到的功能基本也差不多,在UML出现以前就有很多种建模方法出现了(ICONIX就是其中之一),UML最大的贡献是统一了建模符号。和房屋模型不同,软件是个虚拟东西(这里是指软件的本质),没办法用硬纸壳做个模型给你看,只能采用折中的办法使用图形和符号来尽量展示软件的特型。以前众多的方法都是自行设计的图形和符号,UML来了个一锅端,统统改用UML符号来表示,这就好比用阿拉伯数字来表示数字一样,123你看得懂,老外也看得懂,统一的标准保证了通用性。

    所以,UML是一种标准的建模语言(为什么说是语言呢?这根把数学符号称作数学语言一样的道理)。

    现在来讲快速原型。上面讲了UML,只是一个大概,不过在这里只需要和数学符号类比一下就行了。数学家之间用数学符号交流是没有问题的,大家都看得懂。UML在软件专家之间交流也是没有问题的,大家也都看得懂。可是这个系统的参与者并不是所有的人都是专家,还有很多人看不懂UML模型。你已经做了大量的设计,花了大量的时间制作UserCase、Class Diagram、Action Stream等等,站在用户面前一边演示一边长篇大论不厌其烦的介绍系统的特点,我想结果大多数情况只有两种:一种是用户完全震撼,口里念念有词——牛!一种是完全迷惑,一边摇头一边对你说“你说的那些功能到底是什么样子的啊?”。

    嗯,问题来了,到底是什么样子,这才是用户关心的问题。你画的一大堆红线绿线、三角方框圆圈,用户根本不感兴趣,他也不知道那到底是什么(当然他看了心里也许会说果然够专业,果然够复杂,说不定对你立刻产生崇拜心理)。如何回答这个问题呢?快速原型就出场了。

    我设计软件,首先拿一张白纸,从中间笔直画一条竖线,把它分为两个部分,左边是计算机自动处理的部分,右边是用户,中间那条线就是分界线,专业一点叫自动化边界。我们使用电脑,都是希望它能帮我们自动处理一些工作,否则这电脑就没用了。一个软件的功能,说白了也就是自动处理工作的能力。于是我罗列了一大堆系统要实现的功能列在左边(噢,这里我强调,能够这么做的前提是做足了需求分析),用户需要做的工作放在右边。很好,现在我已经明确了这个系统大致的情况,用户需要完成右边的工作,就需要透过中间的自动化边界调用左边的功能(或功能的组合),除此之外别无选择。那么也就是说只要能够向用户展现出自动化边界,也就等于展现出整个系统(因为左边对用户来说是完全封闭的)

    现在我就来开发一个(或者几个,总之要包含所有的内容)小程序,它包含了上述所有用户控制项,用户运行这个程序就跟进后运行真正的系统一样(只是它什么也不会干,只是摆摆样子而已)。现在拿给用户演示:不错吧?很好,就是这样的。那我们就按这个做了?OK,就这样,不过有些地方需要改一下。没问题,你看看那些地方要改的列出来给我吧......

    明白什么是快速原型了吧?

    至于ICONIX,那就是UML+快速原型了。当然ICONIX包含的内容远不止这么简单,不过基本论调就差不多了。注意哦,重点不在快速原型,在UML,在UserCase,别搞错了方向。

 


 

连载:ICONIX 统一建模起步之二 在开始进入设计之前

    抱歉,上个星期太忙,练车又淋了雨,感了点小冒,耽误了些时间,因此这篇来的比较迟。

    我写这个连载的初衷,不过是想向大家介绍介绍ICONIX建模技术而已,但鄙人有个毛病,念头一起就会像射线进入威尔逊云室那样,四散开了去,以至于主线是什么不太容易辨认。好在都是cndev的老朋友,也不是正经八百的写作出书,大家包涵着点就好,呵呵,哈哈。。。

    像今天我要说的,其实根ICONIX没什么关系,我是想用这一段写写自己设计、建模的泛体会(泛者,一般也,广泛也,抽象也,反正不大容易说清楚)。

    ICONIX也好,RUP也好,都是一套规则,诸位如果看过有关RUP的书,大多都讲到软件生命周期、开发周期什么什么周期的,然后讲述步骤,先怎么怎么样,然后怎么怎么样,似乎一切井井有条,未免窃窃心喜:也没什么难的,只要照着做,俺也能成功。等到动手来干点什么,猛然间发现千头万绪,无法下手,根本无法照着书里介绍的一步一步往下做。

    这是为何?答案恐怕翻遍整个书店也找不到,原因其实很简单:它们都只告诉了你做法,却没有告诉你想法。

    做和想,是两个不同的行为,通常来说什么样的想法决定什么样的做法,但是什么样的做法却不一定要有什么样的想法。愚夫愚妇,见人念佛,学而时习之,表面上看上去像模像样,实际效果大大不同,得道的通常都是高僧,大部分职业和尚除了能混碗饭吃以外没什么大用。

    现在我们抛开ICONIX、RUP中和建模无关的东西,单论建模设计,可以明确地说:这两者在做法上没有任何不同,不同的只是想法,即所谓哲学思想不同。用个武侠小说的说法,ICONIX是自外而内,乃是降龙十八掌,RUP则自内而外,乃是一阳指。ICONIX一开始就是以用户界面为导向来驱动整个工程,这和RUP有很大不同(抱歉,这里我说不出RUP的设计思想,因为我对RUP没多大研究,只是泛泛看了看而已,只能肯定RUP不是UI驱动的)。鉴于这个特色,ICONIX特别适合RAD开发者,你用Delphi、VB什么的搞个UI驱动多容易,要让C++搞UI驱动那不是强人所难嘛。

    回到建模和UML来说,ICONIX和RUP两者其实根本是一样的,ICONIX用到的Use Case、Class Diagram之类的东西不会和RUP有什么不同,设计方法也没有差异。所以这方面的内容我基本不会讲,上街随便买本书大堆大堆都是。我以后的部分,大多数都是ICONIX特有的想法和做法。

    让我再稍微跑一下题,谈谈UML的问题。很多书籍资料都介绍了如何使用UML,什么步骤什么规则之类的,我要提醒一下:设计没有规则,建模没有步骤。噢,千万不要误会我的意思,我不是要天马行空的胡乱设计,而是说不要受制于那些条条框框。比如说画画,来画一株梅花,没人规定要先画什么再画什么,先画枝干可以,先画花瓣也可以,只要最后画出来别人看得出来是一株梅花就行。UML也一样,先设计Class Diagram也可以,先设计Activity Diagram也可以。

   不管是画画还是UML,都有一个前提,就是胸有成竹(这里用这个成语的本意)。画梅花的心里早就有了梅花的形象,而一个方案到需要进行UML设计的时候大致是个什么样子,设计者心中也早就有数。所以别指望着UML能无中生有,如果在准备做UML之前还没有成型的思路,那还是先放一放的好。

   好了,今天的胡扯到此告一段落了,接下来我会逐步讲述ICONIX建模的过程,请注意,这些过程除去自然形成的次序外,所有的过程都是并行的。请大家牢记设计的完整性,软件设计和编程是完全不同的,它既不是自顶向下,也不是自底向上,而是一个逐步求精的过程,一开始它就应该是全面的,就好像IE显示GIF图片一样,从模糊到清晰,但从一开始你就能看到全貌,切记切记,不可偏颇。

   最后,这些都是我个人见解,如有雷同实属巧合,欢迎持不同见解者加入讨论。

   最最后,下章预告:域建模和发现类。

连载:ICONIX 统一建模起步之三 域建模之一 发现类

  欢迎大家回到我的连载,从这一期开始,我们正式进入ICONIX的世界。闲话少说,进入正题。

  什么是域建模呢?我们设计一个系统,总是希望它能解决一些问题,这些问题总是映射到现实问题和概念。很明显我们的系统依赖于这些问题,对这些问题进行归纳、分析的过程就是域建模(这个域,指的就是问题域)。

  好了,讲理论大家要昏昏欲睡,我这个小小的连载也没办法把所有的概念说的一清二楚,要是有兴趣的话可以打电话跟我畅谈(前提是不许打手机),现在我来用一个实际的例子讲述域建模。

  用个比较简单的例子吧,本来昨天我是想用HelloWorld来的,可是它实在太简单了,不能说明问题,考虑再三,我使用一个猜数游戏来说明问题。这个游戏相信学过编程语言的都应该很熟悉了:输入一个数,如果猜中了显示“你好棒啊”然后结束,如果不对,系统告诉你是太大还是太小,然后重新让你输入,直到猜中为止。

  现在请拿一张白纸,我们开始归纳问题。

+--------------------------------------------+
|  系统应该准备一个正确答案        |
|                      |
|  玩家可以输入一个答案          |
|                      |
|  系统应该比较玩家输入的答案和正确答案  |
|                      |
|  系统应该显示玩家每次输入的结果     |
+--------------------------------------------+

  遗憾我这个例子还是太过于简单,不过简单也有简单的好处,从这个简单的例子可以看出归纳问题的基本要点。

  第一是不要涉及内部的流程,别出现“如果输入不正确,就怎么怎么样”的句子,这些并不是正确的问题,正确的问题必须明确的,清晰的,如果可能的话全部按照“什么可以干什么”的格式来写。

  第二是不要一开始就进入细节(抱歉,我这个例子例外,它实在是太简单了),包涵太多细节的问题将会是一个长长的清单,这种清单根本没什么用。尽量从最高一层分析,但也不要简单到“用户可以玩游戏”这种笼统的问题。总之一个原则是全面、清晰、明确。要做好问题域分析完全取决于设计师的水平与能力,这就不是可以简单的看看书能达到的了。

  好了,现在我们有了一个系统问题域的清单,可以进行下一步工作:发现类。

  把问题清单中的名词都提出来,得到一个名词列表,这就是类的来源(不过不忙,这只是初步过程)

+----------------+
|  系统    |
|  玩家    |
|  正确答案  |
|  答案    |
|  游戏结果  |
+----------------+

  不是所有的名词都能作为类的,接下来需要进行筛选。

  玩家是参与者,应该放到用例图上去

  系统太笼统,不能成为一个对象的名称

  答案和正确答案容易混淆,但称为输入答案又容易被误解成一个动作,干脆叫做玩家答案

  结果不明确,察看前面的需求,应该分解成错误信息和完成信息

  筛选完毕后,得到下面一个名词列表:

+----------------+
|  正确答案  |
|  玩家答案  |
|  错误信息  |
|  完成信息  |
+----------------+

  这个列表缺少了系统,显得太单薄,回过头再仔细察看需求,应该引入一个游戏引擎,由它来充当调度者。

+----------------+
|  游戏引擎  |
|  正确答案  |
|  玩家答案  |
|  错误信息  |
|  完成信息  |
+----------------+

  同时修改前面的问题域,现在系统已经明确是一个游戏引擎。这种替换当然是一种理想情况,通常都会发生分解和关联,那时候需要扩充问题域,有时候还需要建立新的问题域。

+--------------------------------------------+
|  游戏引擎应该准备一个正确答案      |
|                      |
|  玩家可以输入一个答案          |
|                      |
|  游戏引擎应该比较玩家答案和正确答案   |
|                      |
|  游戏引擎应该显示玩家每次输入的结果   |
+--------------------------------------------+

  现在可以用Rose来制作Class Diagram了,同时可以用RAD工具来搞一个小小的GUI来看看效果,发现类工作到此告一段落。不过问题域分析还没完,类与类之间的关系还没有归纳,当然,那是下一段要讲的事情了。

连载:ICONIX统一对象建模起步之一  面向对象方法简介

    抽空写的,资料也许不全,有什么错误请不吝指教。

    很不幸的,IT是一个随时随地都能冒出一大堆新概念和新词汇的领域,在我写第一个程序的时候恐怕我做梦也没想到现在会发展成这个样子。在大学我学的是结构化程序设计,我想在93年我和我的同学压根就没听说过面向对象这个词,很多同学都是出了校门才开始自学面向对象程序设计的。我起步稍微早一点,二年级读了一本Turbo Pascal 5.5面向对象程序设计的书(还记得是学苑出版社出的)开始了面向对象程序设计的探索。然而那时候我还没有听说过什么设计方法,一切都是随意的,没有人指导我应该如何设计。

    也就是在1993年,面向对象的方法领域在经过三年的发展后,已经进入成熟期,由当初的混乱逐步形成三个主要派别。他们分别是以数据为中心的方法、以脚本为中心的方法和结构化方法。

    以数据为中心的方法基于技术,这些方法诸如实体关系图、数据流图以及状态转换图,这些方法试图通过使用数据为界限来分解系统。(学过数据结构吧,有点像,设计程序先设计数据,然后通过分析数据关系,最后来实现程序,这种方法一般是DBA用得最多的)

    结构化方法则基于代码,首先以OO编程开始,然后展开。结构化方法首先定义需要哪些程序,每个程序应该实现哪些功能,然后按照某种方式把程序组织成一张图,称为结构图。(结构化方法实际上就是按功能分解系统,比如设计一个工资系统,可以按功能划分成录入系统、打印系统、查询系统等等,这大约是传统程序员用得最多的一种方法)

    以脚本为中心就有点不容易说清楚了,简单的说就是使用脚本来进行设计,像比较出名的OBA方法和Alger/Goldstein方法都属于此类。以脚本为中心的方法使用界限来划分系统。(没办法,我没搞过OBA,实在无法用类比的方法说清楚,有经验的朋友帮忙补充一下)

    1993年最佳建模方法当属Rumbaugh的对象建模技术(Object Modeling Technique,OMT)、Jacobson的面向对象软件工程(Object-Oriented Software Engineering,OOSE)和Booch的方法(通常就叫Booch方法)。这三个大牛人在93年一起把这三种方法合成成一个统一的方法。以后三友一起去了Rational公司,开发出UML和RUP统一过程,成为面向对象设计领域的领先标志。

    噢,说了一大堆,却说到UML和RUP去了,还是回到ICONIX来吧。其实ICONIX也是三友发明的,在他们三个没去Rational之前一直是由ICONIX来阐述Booch/Rumbaugh/Jacobson混合方法的(那时还没有UML和RUP)。要是我说的话,ICONIX和RUP并没有本质上的区别(其实都是Booch写的),要说区别主要是态度上。RUP在操作上离地十万八千里,太学术化,完整且忠实于理论,我在运用RUP的时候常常摸不着方向,找不到下手的地方(Seal说是没有剪裁,用RUP一定要剪裁,可是我资质鲁钝,裁来裁去最后不知道要干啥)。ICONIX则从实用角度出发,并不完全忠实于理论,有的地方违反所有三种方法的规则以及语义,并对UML进行了扩展以符合需要。如果你是一个严格的UML信仰者那还是不要来搞ICONIX,但是如果你想快速的应用建模技术到你的工程中去,ICONIX是最佳的选择之一。

    本章到此结束,随后章节我会介绍ICONIX建模的具体方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值