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


一、UML基本构造

UML的基本构造含3种:

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

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

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

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


二、UML中关系

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

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

泛化关系

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

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

实现关系

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

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

依赖关系

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


在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的全局变量

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

class Driver {

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

Car mycar;

public
void drive(){

mycar.run();

}

...

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

public
void drive(Car car){

car.run();

}

}

聚合关系

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

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

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

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

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

class Person{

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

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

brain =
new Brain();

}

}

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


三、总结

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

相同点:

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

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

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【Sunddenly】。

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

时间: 2024-10-17 09:38:11

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

设计模式之UML类图的常见关系

设计模式之UML类图的常见关系 本文来自转载 烧点饭博客 本篇会讲解在UML类图中,常见几种关系: 泛化(Generalization),依赖(Dependency),关联(Association),聚合(Aggregation),组合(Composition). 1.泛化关系 泛化关系是继承或实现的关系,是is a关系,具体表现为类与类的继承,接口与接口的继承,类对接口的实现关系. 2.依赖关系 依赖关系表示为一个类使用另一个类,这种使用关系是具有偶然性的.临时性的.非常弱的,一个类的变化会影

第二个目标:两个月并行学习设计模式、UML、ROSE

两个月并行学习设计模式.UML.ROSE: 参考资料:HEAD_FIRST设计模式(中文版).pdf.[大象Thinking.in.UML].ThinkingInUML.pdf(UML入门教程(中文版).pdf和UML其它详细教程,重点是项目中常见应用的几个图).RationalRos画图.docx 要     求:达到1 全面理解UML知识体系与项目中实际应用.设计模式撑握与项目中应用 第二个目标:两个月并行学习设计模式.UML.ROSE

设计模式奠基石——UML关系转化为代码

1.继承关系(泛化关系) [说明]:继承关系是子类(派生类)继承父类(基类),或者子接口继承父接口的关系.即子类对象"is a" 父类对象,比方鸟是动物. [UML图]: 图解:Animal为父类,Bird类.Fish类.Dog类分别继承了Animal类,它们不仅继承了Animal的公用方法Breath(),同一时候也依据自己的实际须要拓展了相关方法(Fly()方法.Swim()方法.Run()方法). [相应代码]: //Animal类(父类): class Animal { pub

java/android 设计模式学习笔记(2)---观察者模式

这篇来讲一下观察者模式,观察者模式在实际项目中使用的也是非常频繁的,它最常用的地方是GUI系统.订阅--发布系统等.因为这个模式的一个重要作用就是解耦,使得它们之间的依赖性更小,甚至做到毫无依赖.以GUI系统来说,应用的UI具有易变性,尤其是前期随着业务的改变或者产品的需求修改,应用界面也经常性变化,但是业务逻辑基本变化不大,此时,GUI系统需要一套机制来应对这种情况,使得UI层与具体的业务逻辑解耦,观察者模式此时就派上用场了. PS:对技术感兴趣的同鞋加群544645972一起交流. 设计模式

java/android 设计模式学习笔记(14)---外观模式

这篇博客来介绍外观模式(Facade Pattern),外观模式也称为门面模式,它在开发过程中运用频率非常高,尤其是第三方 SDK 基本很大概率都会使用外观模式.通过一个外观类使得整个子系统只有一个统一的高层的接口,这样能够降低用户的使用成本,也对用户屏蔽了很多实现细节.当然,在我们的开发过程中,外观模式也是我们封装 API 的常用手段,例如网络模块.ImageLoader 模块等.其实我们在开发过程中可能已经使用过很多次外观模式,只是没有从理论层面去了解它. 转载请注明出处:http://bl

java/android 设计模式学习笔记(10)---建造者模式

这篇博客我们来介绍一下建造者模式(Builder Pattern),建造者模式又被称为生成器模式,是创造性模式之一,与工厂方法模式和抽象工厂模式不同,后两者的目的是为了实现多态性,而 Builder 模式的目的则是为了将对象的构建与展示分离.Builder 模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程.一个复杂的对象有大量的组成部分,比如汽车它有车轮.方向盘.发动机.以及各种各样的小零件,要将这些部件装配成一辆汽车,这个装配过

java/android 设计模式学习笔记(一)---单例模式

前段时间公司一些同事在讨论单例模式(我是最渣的一个,都插不上嘴 T__T ),这个模式使用的频率很高,也可能是很多人最熟悉的设计模式,当然单例模式也算是最简单的设计模式之一吧,简单归简单,但是在实际使用的时候也会有一些坑. PS:对技术感兴趣的同鞋加群544645972一起交流 设计模式总目录 java/android 设计模式学习笔记目录 特点 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式的使用很广泛,比如:线程池(threadpool).缓存(cache).对

java/android 设计模式学习笔记(7)---装饰者模式

这篇将会介绍装饰者模式(Decorator Pattern),装饰者模式也称为包装模式(Wrapper Pattern),结构型模式之一,其使用一种对客户端透明的方式来动态的扩展对象的功能,同时它也是继承关系的一种替代方案之一,但比继承更加灵活.在现实生活中也可以看到很多装饰者模式的例子,或者可以大胆的说装饰者模式无处不在,就拿一件东西来说,可以给它披上无数层不一样的外壳,但是这件东西还是这件东西,外壳不过是用来扩展这个东西的功能而已,这就是装饰者模式,装饰者的这个角色也许各不相同但是被装饰的对

设计模式学习--Factory Method

What Factory Method:定义一个创建对象的接口,让子类来决定实例化哪一个类.Factory Method使一个类的实例化延迟到其子类. Why Factory Method是一个比较基础的创建型模式,它主要在于由子类决定实例化哪一个类.主要用于框架代码或者工具包中. 适用于如下场景: 1.当一个类不知道它所必须创建的对象的类的时候 2.当一个类希望由子类来指定它所创建对象的时候 3.当类将创建对象的职责委托给多个帮助子类的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的