前言

结构型设计模式,主要研究:

  • 主要有哪些场景使用结构型设计模式;
  • 每种场景应该使用何种设计模式;
  • 以程序中的功能为核心,研究程序功能的组织结构。所以这一章,我们要把“功能结构”作为研究的核心。

下面分别对几种结构型模式加以说明。

1. 适配器模式

示例:适配器模式

使用场景

想要在系统中添加某个功能,类似的功能在其他项目中已经实现,而且经过分析,旧的接口可以经过适当的封装,转换成新的适用于当前系统的接口。这样可以最大程度地复用已有的模块。

原理

通过适配器将已有功能的旧的接口,转换为新的接口,从而实现使已有的功能为新的系统服务的目的。

不适用的情况

以下情况下,不要使用适配器模式:

  • 旧的接口无法转换成新的接口;
  • 写适配器的工作量几乎可以重写所需的功能时。
使用须知

适配器模式其实是一种取巧的做法,在使用时需要慎重考虑。已有功能通过适配器集成到新的系统后,如果出现问题或者需要进行功能扩展,其维护成本是一个需要考虑的问题。例如,已有功能是否使用了过时的技术,或者资料不全,都可能成为项目的风险所在。

本质

适配器模式本质上是通过将一接口封装成另一种接口,实现了模块功能复用。

2. 桥接模式

示例:桥接模式

使用场景

桥接模式是少用继承,多用组合的第一例。
拿菜鸟教程中的例子来说,假如我们现在要实现圆类,包括红色圆和绿色圆两种圆。
首先容易想到的方法是,先写一个圆基类,并添加一个虚(virtual)的绘制函数。然后分别派生出红色圆类和绿色圆类,在子类中分别重新实现绘制函数,将圆绘制成指定的颜色。
在这种简单的例子中,使用继承是没什么问题的。但是假如圆基类还有一个虚函数,此虚函数用于对圆进行旋转。旋转分为两种,顺时针和逆时针旋转。我们想要四种类型的圆:

  • 顺时针旋转的红色圆
  • 顺时针旋转的绿色圆
  • 逆时针旋转的红色圆
  • 逆时针旋转的绿色圆

如何使用继承来实现呢?难道要派生出四个子类吗?如果还有其他功能组合呢?要多少个类呢?这样下去无疑会导致“类的数量爆炸”问题。

原理

结构型模式是研究程序功能组织方法的设计模式。当程序中需要对几种功能相互组合时,应该用组合,不要用继承。
桥接模式下,对于每个功能,应该提取出一个接口类,这个接口类可以有不同的实现。而代表不同的功能接口,可以作为主体类(此例中为圆类)的成员变量,放在一起。需要什么功能,就new哪种接口子类,保存在接口变量中,这样就可以把不同的功能组合起来。
这样一来,类的数量会保持在最低水平。

相对于继承,桥接模式相当于把主体类中的每个虚函数都单独提取出来,构成 一个接口类。这个接口类连接了具体实现和主体类,所以这个模式叫桥接模式。这个名字其实不是很能反映此模式的内涵,其实叫“功能组合模式”更为贴切。

可能有的小伙伴会说,上面的功能其实用C语言实现不是更简单吗?

  • 用一个结构体代表圆,有半径、边框宽度等属性;
  • 每种功能就是一个函数,参数为圆的结构体。

这不就完成了吗?是的!
这个场景下,确实使用C语言实现更简单,不需要使用C++面向对象的任何特性即可实现。可以看出,C++的面向对象的特性,并不是万能的,并不是在所有情况下都是最优的,甚至有时候不如C语言简单直接。从另一个角度说明,大家在面向对象编程的时候,不要把自己的思维局限于面向对象,面向对象思想在一些时候,是不如面向过程的,甚至会把功能结构复杂化,设计到最后导致代码难以维护都是有可能的。

使用须知

桥接模式会导致代码中存在设计模式的代码,会增加代码的理解难度。相对来说,积极作用还是远大于副作用的。

本质

桥接模式的本质是:

如果项目中出现了功能组合的场景,使用继承封装功能是错误做法,要把功能单独提取出来分别封装好以后,再进行组合。


3. 过滤器模式

示例:过滤器模式

使用场景

现有一组对象,我们想要根据不同的过滤条件,筛选出符合条件的一部分对象。

一般写法

最简单粗暴的方法是,在需要进行筛选过滤的地方,直接遍历对象数组,在循环体内进行条件判断。这种写法的优点是简单直接,缺点是如果有多个地方需要使用筛选过滤功能,则需要在多个地方编写重复的代码,这会降低代码的复用性和可维护性。

推荐写法

使用过滤器模式,把筛选功能封装起来使用即可。接口也很好定义,输入对象数组,输出符号条件的对象数组。

本质

过滤器模式的本质是:

当需要从一组对象中过滤出一部分符合条件的对象时,可以考虑将每种过滤功能都封装为一个类,提高代码复用性和可维护性。

4. 组合模式

示例:组合模式

组合模式是一种树形的对象组织结构,在建造者模式已有相关说明,这里不再赘述。

5. 装饰器模式

示例:装饰器模式

使用场景

装饰器模式的研究对象有两个:

  • 已有功能
  • 扩展功能

当我们需要扩展一个类的功能,但是又不想直接在此类上进行改动时,一般的做法是使用继承来实现。继承出来的子类具有父类的属性和方法,在父类基础上可以添加新的功能。
除了继承,还可以使用装饰器模式。装饰器模式是指,新建一个扩展类,将被扩展类的对象作为扩展类的成员变量保存,在扩展类中,操作被扩展类,实现新的方法和功能。
简单来说,装饰器模式就是新建一个类把已有类的功能包装起来,实现新的功能。

使用须知

装饰器模式和继承各有优缺点,使用时要加以权衡,选择最优的方案。

本质

从本质上说:

装饰器模式通过将已有功能作为成员变量整个封装(包装)起来,扩展的新功能,和已有功能耦合最小,互不影响。

6. 外观模式

示例:装饰器模式

本质

这个模式比较简单不再赘述。其本质是:

将已有功能封装起来,提供更易于使用的接口,屏蔽更多实现细节,等于是加了一个中间层。

7. 享元模式

示例:享元模式

按照我们的分类,此模式应该属于创建型模式。它是借助工厂模式来实现一个对象缓冲池,减少对象数量 ,加速创建速度。这里不再赘述。

8. 代理模式

示例:代理模式

应用场景

代理模式就是中介模式。例如我们想要租房,原本租房是发生在租客和房东之间的事务,但中介的出现,虽然会有一定的费用(损耗),但是整个过程的推进会更加顺利。代理模式,用来将两个比较难以直接沟通的功能主体关联起来,实现二者交互。

使用须知

和租房找中介一样,只有在必要的时候才找,否则就是浪费资源,只有在非用不可的时候才建议使用代理模式。

本质

代理模式的本质是:

代理模式封装了沟通所需的所有功能,将两个难以直接沟通的功能主体连接起来,起到了桥梁作用。


结语

结构型模式,就是以功能为核心,研究功能转换、功能调用、功能组合、功能封装等各种情形下,将哪些功能封装到哪些类中,更加高效地实现需求,提升代码的可维护性。

设计模式(四)结构型模式相关推荐

  1. 备战面试日记(3.3) - (设计模式.23种设计模式之结构型模式)

    本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.9 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文章 ...

  2. 设计模式之结构型模式(5种)

    目录 结构型模式(Structural Pattern):怎么构造一个对象(行为.属性) 一.适配器模式 二.桥接模式(Bridge) 三.装饰者模式 设计模式在JAVA I/O库中的应用 案例 使用 ...

  3. JAVA23种设计模式(2)-结构型模式7种

    JAVA23种设计模式(2)-结构型模式7种 把类结合在一起形成更大的结构 适配器模式(adapter) 一句话:将一个类的接口转换成另一种接口.让原本接口不兼容的类可以兼容 这是平时比较常见的一种模 ...

  4. 设计模式 之 结构型模式

    设计模式 之 结构型模式 模式 & 描述 包括 结构型模式 这些设计模式关注类和对象的组合.继承的概念被用来组合接口和定义组合对象获得新功能的方式. 适配器模式(Adapter Pattern ...

  5. 组合模式(Bridge Pattern) – 设计模式之结构型模式

    组合模式(Bridge Pattern) – 设计模式之结构型模式: 目录 组合模式(Component Pattern) 类图 例子1: 过程: 类图: 代码: 抽象组件:PlayerComposi ...

  6. 设计模式(17)-----结构型模式-----外观设计模式

    假如你现在还在为自己的技术担忧,假如你现在想提升自己的工资,假如你想在职场上获得更多的话语权,假如你想顺利的度过35岁这个魔咒,假如你想体验BAT的工作环境,那么现在请我们一起开启提升技术之旅吧,详情 ...

  7. 设计模式3——结构型模式

    结构型模式描述如何将类或对象按某种布局组成更大的结构,它分为类结构型和对象结构型模式,前者采用继承机制来组织接口和类,后者采用组合或聚合来组合对象. 由于组合关系或聚合关系比继承关系耦合度低,满足&q ...

  8. 设计模式:结构型模式-桥接、外观、组合、享元模式

    结构型模式 结构型模式描述如何将类或对象按某种布局组成更大的结构.它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者采用组合或聚合来组合对象. 由于组合关系或聚合关系比继承关系耦 ...

  9. 设计模式_结构型模式学习

    其中,单例模式用来创建全局唯一的对象.工厂模式用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象.建造者模式是用来创建复杂对象,可以通过设置不同的可 ...

  10. 设计模式之结构型模式

    结构型模式 一.适配器模式 (一)定义:适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁,它结合了两个独立接口的功能.这种模式涉及到一个单一的类,该类负责加入独立的或不兼容 ...

最新文章

  1. python使用符号#表示单行注释-【经济金融及Python应用讲义】Python编程规范之注释...
  2. java抓取网页css,Java 读取网页Html资料
  3. 具有JDK 12精简数字格式的自定义精简数字模式
  4. Error: Cannot find module 'webpack-cli'--解决方案
  5. oracle表压缩比,oracle的compress 特性介绍
  6. hdf5 matlab,通过MATLAB将矩阵数据写入HDF5文件中的每个数据类型成员
  7. Java程序员都要懂得知识点:反射
  8. jzoj4313 电话线铺设(最小生成树+最近公共祖先)
  9. kali64位下载怎么是AMD_电脑达人速更 NVIDIA 显卡和 AMD 显卡驱动程序又双叒叕更新啦!...
  10. 【机器学习实战】垃圾分类快速理解机器学习中的朴素贝叶斯(Naive Bayes)
  11. JNI 本地方法注册
  12. native2ascii编码转换
  13. 通过QQ 2012 客户端协议获取clientkey的0x91数据包分析
  14. python创建excel并冻结首行
  15. QT编译程序出现[ui_Widget.h] Error 1
  16. 将一个大文件分割为若干个小文件的方法
  17. 浅谈Docker的安全性支持(上篇)
  18. Java实现递归查询树结构
  19. After Effects Guru: Mastering the Timeline After Effects Guru:掌握时间轴 Lynda课程中文字幕
  20. 大数据营销--中关村大数据产业联盟秘书长赵国栋访谈

热门文章

  1. APP里如何添加本地文本
  2. ViewGroup之getScrollX()
  3. 判断一个数是不是整数
  4. WPF指南之XAML概述
  5. PAT1130. Infix Expression (25) 中序遍历
  6. nodejs python 通信_Nodejs环境实现socket通信过程解析
  7. 带孩子们做环球旅行的读后感_父母带孩子做心理咨询,需要注意哪些事项?
  8. 装mysql最后一步没响应_解决MySQL安装到最后一步未响应的三种方法
  9. threejs坐标转换
  10. ClassCastException:AdaptiveIconDrawable cannot be cast to BitmapDrawable