第三章 类图:基本概念
类图可用来描写叙述系统中各种对象的类型。也可描绘出对象间各种各样的静态关系。此外。类图中也能够秀出类的性质(property)与操作(operation),以及可应用到对象间连接方式的一些限制(constraint)。在UML中,我们用特性(feature)来代表累的性质与操作这两种概念。
1、性质
性质代表类的结构特性(structural feature)。尽管仅仅是一个概念,只是它却能够用两种很不同的表示法来呈现:属性与关联。
2、属性
属性(attributes)表示法用类别四方形中的一行文字来表示性质。
完整语法例如以下:
可见性 名称 : 类型 多重性 = 预设值 { 性质 - 字符串 }
如:
-name:string [1] = "Untitled"{ readonly }
在整个语法其中,仅仅有【名称】部分是必要的。
(1) 可见性标志代表这个属性是public、private或protect。
(2) 属性的名称大约等同于程序语言中的名称 -它说明类怎样參考这个属性的。
(3) 属性的类型代表一种限制条件,说明属性中到底可放入哪一种对象。
(4) 关于多重性(multiplicity)。稍后再解释它。
(5) 预设值(default value)说明在新产生的对象中,假设产生过程中没有指定值给这个属性,那么我们就会把这个值指定给属性。
(6){性质 - 字符串}同意你指明这个属性的一些额外性质。
3、关联
性质的还有一种表示法是关联。属性中可表示出来的信息,差点儿相同也都能够再关联中表示出来。
关联用两个类别中的实线来表示它,箭头会有来源类指向目标类。性质的名称会出如今关联的目标端,同一时候还会加上它的多重性。
关联的目标端所连接的类就是这个性质的形态。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2FpZGFvcXE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
一般来说。倾向于把属性用在小的东西上。比如日期或布尔值等,并且他们通常都是值形态的东西。还有一方面,我会把关联用在有显著意义的类上。比如客户或订单。
同一时候,也倾向于用类四方形画出图种有显著意义的类,这也会导致去用关联;还有一方面,我会把不重要的东西表示成属性。
做出这样的选择。目的主要是为了要强调出重点。
4、多重性
性质的多重性代表它可能会有多少个对象存在。
比較一般的说法是我们能够用一个上限与一个下限来定义多重性。
属性的预设多重性是【1】。
尽管UML的超模型中有这条规则存在,只是如果图中某个属性没有标识出多重属性的话,我们不能因此就如果它的多重性为【1】,由于多重性信息能够隐藏起来。
5、双向关联
双向关联代表一对性质。它们从不同方向彼此连接在一起。
例如以下图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2FpZGFvcXE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
Car类中有性质owner:Person[1],而Person类则有性质cars:Car[*]。
6、操作性
操作是类知道该怎样达成的一些动作。非常明显地。操作就是类中的方法(method)。
在UML中,操作的完整语法为:
可见性 名称(參数列表) : 返回类型 { 性质 -字符串 }
(1) 可见性是public、private或protect
(2) 名称是一个字符串
(3) 參数列表是操作会用到的一串參数
(4)返回类型
(5)性质-字符串代表可应用到此操作的一些性质值。
參数列表中的參数是用跟属性类似的方式来表示的。
其语法例如以下:
方向性 名称 : 形态 = 预设值
(1) 名称、形态与预设值跟属性中的都一样。
(2)方向性代表參数是用来输入(in)、输出(out)或输出入(inout)用的。
评注:把会改变跟不会改变类中状态的操作区分开来是很故意的事。
UML中将query(查询)定义成:仅仅会从类中取出值、不会改变系统的状态的操作。也就说,它不会产生副作用。你能够吧这样的操作加上{query}性质字符串。
还有,我自己喜欢将会改变状态的操作加上modifiers(改动)性质字符。
操作指的是我们可呼出对象的某种东西-它代表程序宣告。而方法则是程序本体。这两种东西在多型存在时,会有非常大差异。比如:假设你有一个基类和三个子类,而每一个子类都覆盖基类的getPrice操作。
这时候。我们就有一个操作,四个方法。
7、一般化关系
对一般化关系明显解释就是继承(inheritance)。
在主流的面向对象语言中,子类会继承超类(superclass)的全部类特性,并且还可能会覆盖不论什么超类的方法。
8、相依性
假设我们该某个元素的定义可能会影响到其它元素,那么这两个元素间就存在着相依性。对类来说相依性存在的原因有好几个:某个类会传送讯息给还有一个类;某个类吧还有一个类当成一部分资料。某个类把还有一个类当成方法中的參数等。
假设系统不断成长,你必须越来越操心该不论什么去控制相依性。假设你没办法控制相依性的话,那么我们系统所做的不论什么改变都会造成涟漪效应,让越来越多东西跟着改变。
表1 本书精心挑选出来一些实用的相依性keyword:
keyword | 意义 |
call | 来源元素回去调用目标元素的某个操作 |
create | 来源元素会产生目标元素的实例 |
derive | 来源元素是由目标元素衍生出来的 |
instantiate | 来源元素是目标元素的实例 |
permit | 目标元素同意来源元素去存取目标元素中的私有特性。 |
realize | 来源元素是目标元素中所定义规格或接口的实现 |
refine | 修饰代表不同语义等级间的关系。 |
substiute | 来源元素是可替代目标元素的 |
trace | 我们用这个相依性来追踪一些东西,比如从需求到类的相依性,或某个模型中的变动是怎样练接到其它模型中变动的。 |
use | 来源元素在实现时须要用到的目标元素 |
一般性原则是尽量减少相依性。特别是相依性会泛滥到系统的一大片区域时。另一点要注意的是:我们应该小心避免循环式相依性,由于它会导致循环性的变动。
9、限制规则
UML同意我们用不论什么东西来描写叙述限制。唯一的规则是:请把限制放在大括号{}内。
有一种选择性的做法是:替限制命名时,把名称放在最前面。后面紧接着一个冒号,像这样{不同意乱伦:夫妻两方不能是兄弟姐妹}
10、何时使用类图
类图是UML的主干,因此你能够发现随时都得到它们。
类别图的最大麻烦在于里面包括太多东西了。所以它们可能会被过度使用。以下是一些使用上的提示:
A、不要试着用到全部能够使用的表示法。先简单用本章所提及的一些东西:包含类别、关联、属性、一般化关系与限制等。
至于高级的东西。仅仅在你认为有须要时再去用它们。
B、我发现到概念性的类图在探索某个企业的领域语言时特别实用。想要这么做时,你必须努力保持不去讨论软件本身,并且尽可能使用很easy的表示法。
C、不要画出包括全部东西的模型。相反地,把重心放在关键地方。持有一些经常使用的到、时时更新的图,比起持有非常多被人遗忘掉、过时的图还好。
使用类图的最大危急在于你可能会过度把焦点放在结构上,而忽略系统中的行为。