转载

设计模式学习---UML常见关系的实现

一、UML基本构造

UML的基本构造含3种:

(1) 事物(4种):结构事物,行为事物,分组事物,注释事物

(2) 关系(4种):泛化关系,实现关系,依赖关系,关联关系

(3) 图(10种):用例图,类图,对象图,包图,组件图,部署图,状态图,活动图,序列图,协作图

事物是对模型中最具代表性的成分的抽象;关系把事物结合在一起;图聚集了相关的事物。

二、UML中关系

UML 中关系描述的是:类与类, 类与接口, 接口与接口之间的关系。UML中的关系主要包括: 泛化 (generalization) 关系,  关联 (association)关系( 关联, 聚合, 组合),  依赖 (dependency)关系, 实现 (realization)关系。其中, 关联依赖 关系是按 类之类关系的 紧密的程度 划分的,它们之间的关系强度:

依赖 <<< 关联 <<< 聚合 <<< 组合

泛化关系

泛化关系 是一个类(称为子类、子接口) 继承 另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系

设计模式学习---UML常见关系的实现

在Java中 此类关系通过关键字 extends 明确标识,在设计时一般没有争议性

实现关系

实现关系 指的是一个class类实现interface接口(可以是多个)的功能;实现是类与接口之间最常见的关系

设计模式学习---UML常见关系的实现

在Java中 此类关系通过关键字 implements 明确标识,在设计时一般没有争议性

依赖关系

依赖关系 : 也是类与类之间的连接;表示 一个类依赖于另一个类的定义 ; 依赖关系总是 单向 的 。可以简单的理解,就是一个类A使用到了另一个类B,而这种使用关系是具有 偶然性的临时性的非常弱的 ,但是B类的变化会影响到A。 现实世界层面 表现为:比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖; 代码层面 表现为:类B作为参数被类A在某个method方法中使用

设计模式学习---UML常见关系的实现 在Java 中 依赖关系体现为:  局部变量方法中的参数 ,和 对静态方法的调用 。如下面的例子:Driver类依赖于Car类,Driver的三个方法分别演示了依赖关系的三种不同形式

class Car {

public static void run (){

System . out . println ( 汽车在奔跑 );

}

}

class Driver {

// 使用形参方式发生依赖关系

public void drive1 ( Car car ){

car . run ();

}

// 使用局部变量发生依赖关系

public void drive2 (){

Car car = new Car ();

car . run ();

}

// 使用静态 方法发生依赖关系

public void drive3 (){

Car . run ();

}

}

关联关系

关联关系 : 表示类与类之间的联接, 它使一个类 知道 另一个类的 属性方法 。关联可以使用 单箭头 表示 单向关联 , 使用 双箭头不使用箭头 表示 双向关联 , 不建议使用双向关联;关联有 两个端点 , 在每个端点可以有一个 基数 , 表示这个关联的类可以有几个实例。常见的基数及含义如下 

0..1: 0 或1 个实例

0..*:  对实例的数目没有限制

1 :  只能有一个实例

1..*:

至少有一个实例

关联体现的是 两个类 、或者 类与接口 之间 语义级别 的一种 强依赖关系 ,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。代码层面表现为:被关联类B以 类属性 的形式出现在关联类A中,也可能是关联类A 引用 了一个类型为被关联类B的全局变量

设计模式学习---UML常见关系的实现

在java 中 关联关系是使用 实例变量 实现的,依然使用如下:Driver和Car的例子,使用方法参数形式可以表示依赖关系,也可以表示关联关系。在本例中,使用 成员变量表达 这个意思:车是我自己的车,我"拥有"这个车。使用 方法参数表达 :车不是我的,我只是个司机,别人给我什么车我就开什么车,我使用这个车。

class Driver {

// 使用成员变量形式实现关联

Car mycar ;

public void drive (){

mycar . run ();

}

...

// 使用方法参数形式实现关联

public void drive ( Car car ){

car . run ();

}

}

聚合关系

聚合关系 : 关联关系的一种特例,是强的关联关系。聚合是 整体个体 之间的关系,即 has-a 的关系,此时整体与部分之间是 可分离 的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。现实层面表现为:比如计算机与CPU、公司与员工的关系等;代码层面表现为:和关联关系是一致的,只能从语义级别来区分

设计模式学习---UML常见关系的实现

在java 中 聚合关系也是使用 实例变量 实现的,从java 语法上是分不出关联和聚合的,关联和聚合的区别纯粹是概念上的,而且严格反映在语义上。聚合在代码中的实现是比较灵活的, 大雁 聚合 为雁群 ,只要大雁类是雁群的成员变量就行了,代码有两种方式都是聚合:

设计模式学习---UML常见关系的实现

第一种方式: 通过传参 方式

这种方式一般用在大雁WideGoose是抽象类(父类)的时候,这时候,就可以传入不同的子类,这样就会使它调用的时候很灵活

class WirdGooseAggregate {

private WideGoose widegoose ; // 成员变量定义大雁

public SetWideGoose ( WideGoose w ){ // 通过传参得到大雁的对象

this . widegoose = w ;

}

}

第二种方式:通过设置初始值

这种方式就是写死了,是不能灵活的,但是这样写也有它的好处,就是定义了一个初始值。在状态模式中就用到了这种方式,其实是定义了一个初始对象。

class WirdGooseAggregate {

private WideGoose widegoose ; // 成员变量定义大雁

public SetWideGoose (){ // 通过传参得到大雁的对象

widegoose = new WideBlackGoose (); //WideBlackGoose WideGoose 的子类

}

}

主要注意的是:关联关系中两个类是处于相同的层次, 而聚合关系中两不类是处于不平等的层次, 一个表示整体, 一个表示部分。同时,由上图可知聚合关系一般使用setter方法给成员变量赋值

组合关系

组合关系 : 也是关联关系的一种特例,他体现的是一种 contains-a 的关系,这种关系比聚合更强,也称为 强聚合 ;它同样体现整体与部分间的关系,但此时整体与部分是 不可分 的,整体的生命周期结束也就意味着部分的生命周期结束,并且合成关系不能共享; 现实层面 表示为:比如你和你的大脑;表现在 代码层面 ,和关联关系是一致的,只能从语义级别来区分。需要注意的是:组合跟聚合几乎相同,唯一的区别就是"部分"不能脱离"整体"单独存在,就是说, "部分"的生命期不能比"整体"还要长。

设计模式学习---UML常见关系的实现

在java 中 组合关系也是使用 实例变量 实现的,在代码中 组合关系 就没有这样灵活了,它是强耦合的,它生命周期是 同生同死 的关系。我们知道一个对象被实例的时候就是我们意义上的"生",因此我们就把组合的对象放在被组合对象的构造函数中:

class Person {

private Brain brain ; // 成员变量定义 大脑

public Bird (){ // 构造函数中实例化翅膀对象

brain = new Brain ();

}

}

由上述可知,组合关系是在构造函数中实现的

三、总结

对于 继承实现 这两种关系没多少疑问,它们体现的是一种类与类、或者类与接口间的 纵向关系其他的四者 关系则体现的是类与类、或者类与接口间的 引用横向关系 ,是比较难区分的,有很多事物间的关系要想准备定位是很难的,前面也提到,这几种关系都是语义级别的,所以从代码层面并不能完全区分各种关系;但总的来说,后几种关系所表现的强弱程度依次为:组合>聚合>关联>依赖。它们之间的联系如下:

相同点:

组合与聚合都是 整体部分 的关系,组合的关系更强一点,对组合关系来说,如果失去部分,整体也将不存在了

不同点:

代码实现层面上来看 : 组合:在整体的构造器中实例化部分,这个部分不能被其他实例共享。整体与部分的生命周期是同步的。而聚合关系的部分,可以在构造器中通过参数传递的形式进行初始化

从数据库的层面上看

:     组合关系需要级联删除,而聚合关系不需要

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。

如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。

如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【Sunddenly】。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

正文到此结束
Loading...