本节和大家一起学习一下UML精粹中的类图,主要从六个方面向大家介绍,希望通过本节的学习你对UML精粹中类图的知识有一定的了解,下面让我们一起来学习UML类图吧。
UML精粹-类图
一直觉得自己对UML的理解还远远不够深刻,最近在画即时消息系统核心模块的类图时越有这种感觉。急忙找来老马的<<UML精粹>>很补一下下。***篇,是关于UML类图的:
一、区分操作operation和方法method
操作是对对象提出的事情(过程说明),而方法则是过程体。例如,超类的getPrice()就是一个操作,而他的所有子类的getPrice()则是方法。
操作可分为恒态操作query和改态操作modifier。区别是他们能够改变可观察到的状态。恒态操作的一个优点是改变恒态操作的执行顺序而不改变系统的行为,所以突出恒态操作是有益的,通常的习惯是,使改态操作不带返回值,这样,有返回值的就是恒态操作,虽然这样有时会感到不便。(Meyer的‘改态操作-恒态操作分隔原理’)。
二、依赖
UML精粹中类图一般在如下两周情况下会发生依赖关系:一个类把消息发给另外一个类;一个类以另外一个类作为数据部分。
过于复杂的依赖可能会导致‘涟漪效应’。这种效应的结果是,以后万一有改动,就会牵一发而动全身。
《常用表示依赖的词汇》
call源调用目标中的操作
create源创建目标的实例
derive源由目标导出
instantiate源是目标的一个实例(如果源是一个类,则这个类本身就是类的一个实例,也就是说,目标类是个一元类)
permit目标允许源访问目标的私用特征
realize源是由目标定义的规约或接口的一个实现
refine源可以是一个设计类,目标是相应的分析类
substitute源可以置换目标
trace用于追踪诸如需求到类或者一个模型中的改动如何连接到别处的改动
use源要求目标为其实现
设计依赖的原则:
1。使依赖减至极少,特别是在他们跨越系统的大区域时;
2。提防循环依赖,因为他们会引起循环的改动;
3。试图表明一个类图中的所有依赖是徒劳无功的,依赖太多,改动也多,当这个依赖和题目由直接联系才画出来;
4。严格将表象与领域分开也是一个好习惯。
三、聚合与组合
UML精粹中类图的聚合aggregation是整体和部分的关系。很多开发人员认为聚合很重要,即使他们基于的理由不同。于是,UML包含了聚合。但是,聚合在UML中没有任何语义!而组合composition则不同,它表示一个类可以是多个其他类的成分,但任一实例必须只能是一个拥有者的成分,即它只属于一个拥有者。例如,点的实例可以是多边行的部分或者是一个圆形,但二者不能兼是。这个规则也叫做‘非共享规则’。其次,如果这个多边行被删除了,应该自动确保它拥有的所有点也都被删除。
在UML中略去聚合,只使用组合。对于其他人的类图中出现的聚合,因该仔细分析,不同的作者或者开发团队对使用聚合可能有不同的目的。
四、分类与泛化多重分类与动态分类
提防‘子类都是is-a关系’这样的想法。有时候使用继承可能造成不合适或职责混淆。看下面的短语:
1)Shep是一只牧羊犬
2)牧羊犬是一只犬
3)犬是动物
4)牧羊犬是一属Breed
5)犬是一个种Species
由1-4可以推出Shep是一属,而由2-5可推出牧羊犬是一个种,这样看起来就不大合适了。这是因为,在这里面并不是所有的关系都是泛化(牧羊犬类型是犬类型的一个子类),有些是分类(对象Shep是牧羊犬类型的一个实例)。泛化是传递的,分类则不然。
为什么会把Shep对象和其他类扯到一起呢?看看分类的定义,分类指的是对象及其类型之间的关系。主流编程语言都假定,一个对象只属于一个类。但在多重分类中,一个对象可以表述为若干类型,他们不一定是用继承来连接沟通的。
五、何时使用类图
1。尽量使用简洁的表达方式(类,关联,属性,泛化,约束),少用高级的图示法;
2。不要对所有事情都绘制类图,而要集中考虑关键方面
用类图***的危险就是,你可能全神贯注于结构而忽略行为。所以,绘制UML精粹中类图的同时,***连同使用某种形式的行为技术。
六、按照契约进行设计
断言是按契约设计的和行,按契约设计使用了三中特定的断言:前置条件pre-condition,后置条件post-consition和不变式invariant。前置条件和后置条件用于操作。后置条件是操作执行后‘事前就该如此’的一种陈述(比如计算的公式,你输入参数,我就按这个公式给你结果),他用以表示‘我不做什么而不是我们如何去做’。换言之,他是把接口和实现分开的一种有用的方法。前置条件是在操作执行前,我们指望事情如何的一种陈述(比如对输入值的要求)。前置条件明确了‘谁负责核查输入条件的正确性’(比如输入的参数置的取值范围)。这很重要,如果没有这样明确的职责陈述,则可能是‘核查过少’(没有检查)或者‘核查过多’(双发都检查)。
通过前置条件和后置条件,我们可以对异常Exception得出一个比较深刻的理解:异常发生在启用操作时,其前置条件满足,但该操作却不能回送使后置条件满足的结果。不变式是加在与给定类所有公用操作相关的前置条件和后置条件之上的。在方法执行中,不变式可以为假,但是它在任何别的对象可对接受者做任何事情时它就因该回复成真。
断言对子类的构造可起到独特的作用。继承的危险之一是,你可能定义一个新的子类,但它和超类的操作不相容。断言减少了这种情况出现的机会。类的不变式和后置条件必须用于所有子类。子类可以选择加强这些断言,但不能削弱它们。另一方面,前置条件却不能加强,但可以减弱。(在动态绑定中,如果一个子类加强前置条件,则当它用于子类时,超类的操作就会失败)
【编辑推荐】