这学期接触了《系统设计与分析》这门课,重要,但是觉得挺不好学的,因为好像很多决策都不存在很明确的界限。所以,多思多想多交流吧,看一些相关的案例还是有些帮助的。现在把自己学习时的一些想法与大家分享,初写这类博客,有错请指出,共同进步。
概念类图(conceptual class diagram)其实是领域模型(domain model)中的一个术语,要理解概念类图,先要了解一下什么是领域模型。
什么是领域模型?
领域模型是对领域内的概念类或者现实世界中对象的可视化表示。它阐述了领域中的重要概念。我比较粗浅的理解是,领域模型是描述一个特定的领域内,有哪些对象,他们之间存在什么样的联系。具体更详细的解释可以看百度百科或者英文的维基百科。
回到概念类图的绘制,如何画概念类图呢?一般来说,可以分为一下三个步骤:
1、寻找概念类;
2、绘制为UML类图中的类;
3、添加关联和属性。
接着,通过一个实际例子来理一下这三个步骤具体是怎么做的。
给定如下一个场景,对这个场景绘制概念类图:
Priests and Devils
Priests and Devils is a puzzle game in which youwill help the Priests and Devils to cross the river within the time limit.There are 3 priests and 3 devils at one side of the river. They all want to getto the other side of this river, but there is only one boat and this boat can onlycarry two persons each time. And there must be one person steering the boatfrom one side to the other side. In the flash game, you can click on them tomove them and click the go button to move the boat to the other direction. Ifthe priests are out numbered by the devils on either side of the river, theyget killed and the game is over. You can try it in many ways. Keep all priestsalive! Good luck!
第一步:寻找概念类;
概念类如何寻找?通常有这样的三种方法:1、重用和修改现有的模型;
2、使用分类列表;
3、通过识别名词短语寻找概念类。
其中,方法1和2这里不说明了,有兴趣的同学可以自己去拓展。下面通过方法三,识别名词短语来寻找概念类,我觉得这是比较常用而且大家直觉上都会这么做的。
那要寻找怎么样的名词才是有用的呢?通常我们寻找那些描述一样东西的,描述人的,工具,物品等这种实实在在的名词,当然,还有一些比如描述领域的(如game等),这些类型的名词也要注意。从场景的描述中,我们可以找出如下一些描述对象的名词:
Priest Devil game river time side boat person
找出了这些类,我们就要分析这些是不是全部都是必须的。
先看Priest和Devil,这两个都是描述在这个游戏里的两个主要的操作对象,因此要保留;
game:game在这里圈定了这些活动发生的范围,是描述这些活动发生的领域,除此之外从文本中不能明显看出还有什么信息。因此,把game作为待定,在分析完全部之后再做决定;
river: river在场景描述中只是相当与一个装饰场景的,在整个游戏的各种活动和操作中,并没有涉及到对river这种对象的直接操作,因此不保留,去掉;
time:游戏中有一个时间限制,因此时间在这个游戏中是有起到作用的,建议保留;
side:游戏中有两个side,每个side上有主角的数目,而且这些数目关系到游戏的状态(win or over),因此保留;
boat:显然,游戏中boat也是一个要操作的对象,保留;
person:person实际上是Priest和Devil的父类,在这里选择保留;
这样,我们经过分析,就抽取出了七个概念类。
第二步:绘制UML类图,如下:
第三步:添加关联和属性。
要添加关联,先得了解一下什么是关联,有哪些关联。
什么是关联(association)?关联,是类(更精确第说,是类的实例)之间的关系,表示有意义和值得关注的连接。
常见的关联有:
关联(association):强关系,两者之间存在着某种联系;
泛化(generalization):换个词,“继承”,大家就都知道了,泛化就是对一个父类的继承;
聚合(aggregation):表示两个对象可以分开存在,存在部分和整体的关系;
组合(composition):这个也是表示部分和整体之间的关系,但是要求两者必须是同时存在下才有意义的;
依赖(dependence):对象独立存在,一个对象依赖于另外一个对象是说,另外一个对象作为该对象的成员或者参数;
关联如何表示?
关联被表示为类之间的连线,并且冠以首字母大写的关联名称。关联的末端可以包含多重性表达式,用于指明类的示例之间的数量关系。
多重性(multiplicity):表达一个类A有多少个实例可以与另一个类B的一个实例关联。
了解这些之后,我们来分析一下如何给这些类添加关联。
Priest和Devil继承了person;
一个boat可以载两个person;
一个game里有6个person,也即3个Priest和3个Devil;
一个game里还包含一个boat,一个time,两个side;
Devil可以杀死Priest(当然有前提条件);
将关联和多重性添加到已有的类图中得到如下图所示的模型:
到了这里,已经离成功不远了,最后我们还需要添加属性。
属性(attribute):是对象的逻辑数据值。
这里只选boat和side来分析何时加入属性。
首先,先看一下属性这个词的定义:
看完游戏的文字描述,可能很容易就会发现,与boat和side有关联的数据值有:船上有几个人,岸上有几个人。那是否要为boat和side引入这些属性呢?
看一下参考书里是怎么说的“当需求(例如,用例)建议或暗示需要记住信息时引入属性。”
放到游戏中去看,岸上有几个Priest和Devil关系到整个游戏的状态,是终止还是继续,因此,对side对象我们引入这些属性;
对于boat,是位于river的左边还是右边,这也关系到游戏下一步可以怎么进行,因此有必要引入这个属性;而对于船上有几个人,在多重性上,我们已经表示了一个船可以与两个person实例有关联,因此就不引入这个属性。
加入属性后,我们就得到了如下图的概念类图:
当然,这些只是我个人的理解所作出来的图,也有另外一些人的其他画法,例如:
【小结】
领域模型,在我的理解上,就是把问题领域内的,什么人(对象),之间怎么联系,做什么,把这些点表示出来就差不多了。概念类图不同于设计类图,不需要展示类的方法,你只要表示出有哪些类,类与类之间怎么协作就可以了。
【说明】
如有知识点或表述不正确的,欢迎指出,共同进步。
参考书籍《UML与模式应用》第三版
原创文章,转载请注明出处。