c++ 设计模式之UML图

标签: C++

前言

可能自己看的设计模式图还是比较少,经常忘记,那就整理网上以及各种书籍里面的知识吧,以后翻看,同时也给后来者以及同行一个交流学习的地方。有不对之处请指出。

图片和文字摘抄自网络和《大话设计模式》,如果有侵权请及时联系删除。

 

UML简介

Unified Modeling Language (UML)又称统一建模语言或标准建模语言,是始于1997年一个OMG标准,它是一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持,包括由需求分析到规格,到构造和配置。 面向对象的分析与设计(OOA&D,OOAD)方法的发展在80年代末至90年代中出现了一个高潮,UML是这个高潮的产物。它不仅统一了Booch、Rumbaugh和Jacobson的表示方法,而且对其作了进一步的发展,并最终统一为大众所接受的标准建模语言。

说了这么多,我认为,UML其实有点类型思维导图,就是用来将你要写的程序做一个整体设计,用来搭建一个整体框架。而这个框架就是整理出你写的代码之间的关系。这些主要是类与类之间的关系。

 

类与类之间的关系

类与类之间的包括:泛化(继承)、实现、关联、聚合、组合、依赖

 

(1)依赖关系:虚线+箭头

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

class Car{};

class House{};

class Person

{

void buy(Car& car){}

void buy(House* pHouse){}

};

(2)关联关系:实线+箭头表示

看到其他博客说实线+箭头是单向关联实线(不带箭头)是双向关联,不知道是不是这样,有待验证,我在有的书籍和网络材料上看到两种方式确实都出现过。看到另外一篇博客这样写:有双向关联和单向关联,双向关联有两个箭头或者没有箭头,单向关联有一个箭头,表示关联的方向。

 

释义:他体现的是两个类、或者类与接口之间语义级别的一种强依赖关系,比如我和我的朋友;这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的、关联可以是单向、双向的;表现在代码层面,为被关联类B以类属性的形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量; 基数 :连线两端的数字表明这一端的类可以有几个实例,比如:一个鸟应该有两只翅膀。如果一个类 可能有无数个实例,则就用‘n’来表示。关联、聚合、组合是有基数的。 

基数表示含义
0..10个或者1个
1只能1个
0..*0个或者多个
*0个或者多个
1..*1个或者多个
3只能3个
0..30至3个
3..133至13个
//单向关联

class Person{};

class Friend

{

Person* mpPerson;

};

//eg.2

//双向关联

class A;

class B

{

A* pA;

};

class A

{

B* pB;

};

//eg.3

//自身关联

class C

{

C* pC;

};

(3)接口实现:虚线+空心三角(implement / interface)

释义:指的是一个class类实现interface接口(可以是多个)的功能;实现是类与接口之间最常见的关系;在Java中此类关系通过关键字implements明确标识,在设计时一般没有争议性;(暂时没看到有关c++的描述,摘抄的是JAVA的描述)

 

 

(4)继承关系(泛化关系):实线+空心三角。

 释义: 继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。在Java中继承关系通过关键字extends明确标识,

父类 父类实例=new 子类();

class Animal{};

class Tigger : public Animal{};

class Dog : public Animal{};

Animal* pAnimal = new Dog;

(5)聚合关系:实线+空心菱形,

在《大话设计模式》中,提到使用的是实线箭头+空心菱形表示,可能是不同是用法,但表示的是一个意思。看到也要能看懂。

释义:聚合是关联关系的一种特例,他体现的是整体与部分、拥有的关系,即has-a的关系,此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;比如计算机与CPU、公司与员工的关系等,再例如汽车、发动机、轮胎,一个汽车对象由一个发动机对象,四个轮胎对象组成。当类之间有整体-部分关系的时候,我们就可以使用组合或者聚合

等;表现在代码层面,和关联关系是一致的,只能从语义级别来区分;

class CPU{};

class Memory{};

class Computer

{

CPU* mpCPU;

Memory* mpMemory;

};

(6) 组合关系(合成关系,composition):实线+实心菱形。

释义:组合也是关联关系的一种特例,他体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合;他同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束;比如你和你的大脑;表现在代码层面,和关联关系是一致的,只能从语义级别来区分;一旦整体对象不存在,部分对象也将不存在。部分对象与整体对象之间具有共生死的关系

在《大话设计模式》中,提到使用的是实线箭头+实心菱形表示,可能是不同是用法,但表示的是一个意思。看到也要能看懂。

class Leg{};

class Arm{};

class Person

{

Leg mLeg;

Arm mArm;

};

 

(1)‘+’表示public,

(2)‘-’表示private,

(3)‘#’表示protected

 

 

六、关系之间的区别

1.聚合与组合

(1)聚合与组合都是一种结合关系,只是额外具有整体-部分的意涵。

(2)部件的生命周期不同

聚合关系中,整件不会拥有部件的生命周期,所以整件删除时,部件不会被删除。再者,多个整件可以共享同一个部件。
组合关系中,整件拥有部件的生命周期,所以整件删除时,部件一定会跟着删除。而且,多个整件不可以同时间共享同一个部件。

(3)聚合关系是“has-a”关系,组合关系是“contains-a”关系。

2.关联和聚合

(1)表现在代码层面,和关联关系是一致的,只能从语义级别来区分。

(2)关联和聚合的区别主要在语义上,关联的两个对象之间一般是平等的,例如你是我的朋友,聚合则一般不是平等的。

(3)关联是一种结构化的关系,指一种对象和另一种对象有联系。

(4)关联和聚合是视问题域而定的,例如在关心汽车的领域里,轮胎是一定要组合在汽车类中的,因为它离开了汽车就没有意义了。但是在卖轮胎的店铺业务里,就算轮胎离开了汽车,它也是有意义的,这就可以用聚合了。

3.关联和依赖

(1)关联关系中,体现的是两个类、或者类与接口之间语义级别的一种强依赖关系,比如我和我的朋友;这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。

(2)依赖关系中,可以简单的理解,就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是B类的变化会影响到A。

4.综合比较

这几种关系都是语义级别的,所以从代码层面并不能完全区分各种关系;但总的来说,后几种关系所表现的强弱程度依次为:

组合>聚合>关联>依赖;

 

 

对于继承、实现这两种关系没多少疑问,他们体现的是一种类与类、或者类与接口间的纵向关系;其他的四者关系则体现的是类与类、或者类与接口间的引用、横向关系,是比较难区分的,有很多事物间的关系要想准备定位是很难的,前面也提到,这几种关系都是语义级别的,所以从代码层面并不能完全区分各种关系;

但总的来说,后几种关系所表现的强弱程度依次为:组合>聚合>关联>依赖;

聚合跟组合其实都属于关联 只不过它们是两种特殊的关联 因为本是同根生 所以它们之间难免会有相似之处 下面让我们一起来看一下它们之间有何不同

聚合与组合的概念相信不用我在此赘述大家就已经了解了 下面直接上例子

程老师的《大话设计模式》里举大那个大雁的例子很贴切 在此我就借用一下 大雁喜欢热闹害怕孤独 所以它们一直过着群居的生活 这样就有了雁群 每一只大雁都有自己的雁群 每个雁群都有好多大雁 大雁与雁群的这种关系就可以称之为聚合 另外每只大雁都有两只翅膀 ,大雁与雁翅的关系就叫做组合。 有此可见 聚合的关系明显没有组合紧密 大雁不会因为它们的群主将雁群解散而无法生存 而雁翅就无法脱离大雁而单独生存——组合关系的类具有相同的生命周期,而聚合可以具有各自的生命周期。

 

 

 

 

DIP(依赖倒置: Dependency Inversion Principles)。 其含义就是父类调用子类的操作(高层模块调用低层模块的操作),低层模块实现高层模块声明的接口。这样控制权在父类(高层模块),低层模块反而要依赖高层模块。
 

主要参考摘抄以下文章:

https://www.cnblogs.com/huaxingtianxia/p/6590351.html

https://blog.csdn.net/shift_wwx/article/details/79205187

https://www.cnblogs.com/olvo/archive/2012/05/03/2481014.html

https://www.cnblogs.com/olvo/archive/2012/05/03/2481014.html

以及 Candidate for Master’s Degree School of Computer Wuhan University 的K_Eckel总结的c++23种设计模式

版权声明:本文为lxj362343原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lxj362343/article/details/109462713

智能推荐

【设计模式】UML类图

UML类图 依赖 泛化关系(generalization) 实现关系(Implementation) 关联关系(Association) 单向一对一关系 双向一对一关系 聚合关系(Aggregation) 组合关系(Composition) UML——Unified modeling language UML (统一建模语言) UML本身是一套符号的规定,就像数学 符号和化...

设计模式必修之---彻底看懂 UML 类图

类图: 类图分三层, 第一层显示类的名称,如果是抽象类,就用斜体显示 第二层,为类的特性,通常就是字段和属性 第三层是类的操作,通常是方法或者行为。 UML规定操作的表示方式为: 可见性 名称(参数列表) [ : 返回类型] 其中: “可见性”的定义与属性的可见性定义相同。 “名称”即方法名,用一个字符串表示。 “参数列表”表...

C++笔记(五) UML/设计模式(简单工厂模式及工厂模式)

一、UML(统一建模语言) 模型:对问题的书面上的无歧义文字或图形的描述,简言之,模型是对现实的简化。 建模:对现实系统进行适当的过滤,用适当的表现规则描述出简介的模型问题。 UML:是一种基于面向对象的可视化建模语言。UML采用了一组形象画的额图形符号作为建模语言,使用这些符号可以形象的描述系统的各个方面。UML通过建立图形之间的各种关系来描述模型。 UML建模工具:Rose,用的比较少;用例图...

23种设计模式C++源码与UML实现--建造者模式

建造者模式 代码仓库地址:建造者模式 Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种。Builder模式是一种对象创建模式之一,用来隐藏复合对象的创建过程。他把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象。 对象的创建:Builder模式是为了对象的创建而设计的模式-创建的是一个复合对象,被创建的对象为一个具有复合属性的...

23种设计模式C++源码与UML实现--桥接模式

桥接模式 Bridge模式,又叫做桥接模式,是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为让类承担不同的责任。它的主要特点是把抽象(Abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及对它们的功能扩展。 UML实现如下: client Bridge模式的使用者 Abstration 抽象类接口(接...

猜你喜欢

23种设计模式C++源码与UML实现--适配器模式

适配器模式 github代码仓库 将一个类的接口转换为客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 UML图如下: 适用性 你想使用一个已存在的类,而它的接口不符合你的需求。 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作 你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配他们的接口,对象适配器可以适配...

web安全简易规范123

web安全,大公司往往有专门的安全开发流程去保证,有专门的安全团队去维护,而对于中小网络公司,本身体量小,开发同时兼带运维工作,时间精力有限,但是,同样需要做一些力所能及的必要的事情。有时候,安全威胁并不是因为你的防盗窗被人撬开了,而是你晚上睡觉的时候忘了关门,而关上门对开发来说也许只是举手之劳。 1、不要用root,确定使用的中间件和框架是否默认打开了后门 我们总会在线上使用部署一些中间件、开源...

css弹性盒模型详解----justify-content

本篇文章详细介绍justify-content 效果演示如下: 效果演示如下: 效果演示如下: 效果演示如下: 效果演示如下...

html5拖放--15行js代码实现两个div内容互换

本文首发于我的个人博客:http://cherryblog.site/ ,欢迎大家前去参观 本文项目地址,sortable插件地址:https://github.com/sunshine940326/sortable demo地址:https://github.com/sunshine940326/drag 在写我们后台的管理程序中需要有一个拖放的功能,然后我们有一个这样的功能,实现11个固定且大...

git切换分支报错,不管什么标题名字,都报非法字符,所以就不起名字了。

切换分支的时候,报了标题这么个错误,error: ”xxx did not match any file(s) known to git. 看见不能切换分支,我首先 git status 查看了一下当前状态,如下图 然后,就会发现,其实我的这个错误非常明显,就是在我的 beat 分支下有文件修改,所以切换不了。ok,解决方法: 1. 如果修改的这些文件没什么用,完全可以删除。(我这儿的...