作者:TerryLee  创建于:2006-06-01 出处:http://terrylee.cnblogs.com/archive/2006/06/01/designpattern_articles_structpattern.html 收录于:2013-02-28

结构型模式概述


结构型模式,顾名思义讨论的是类和对象的结构,它采用继承机制来组合接口或实现(类结构型模式),或者通过组合一些对象,从而实现新的功能(对象结构型模式)。这些结构型模式,它们在某些方面具有很大的相似性,仔细推敲,侧重点却各有不同。

Adapter模式:     通过类的继承或者对象的组合侧重于转换已有的接口;
Bridge模式:       通过将抽象和实现相分离,让它们可以分别独立的变化,它强调的是系统沿着多个方向的变化;
Decorator模式: 采用对象组合而非继承的手法,实现了在运行时动态的扩展对象功能的能力,它强调的是扩展接口;
Composite模式:模糊了简单元素和复杂元素的概念,它强调的是一种类层次式的结构;
Façade 模式:     将复杂系统的内部子系统与客户程序之间的依赖解耦,它侧重于简化接口,更多的是一种架构模式;
Flyweight模式:  解决的是由于大量的细粒度对象所造成的内存开销的问题,它与Façade模式恰好相反,关注的重点是细小的对象;
Proxy模式:       为其他对象提供一种代理以控制对这个对象的访问,它注重于增加间接层来简化复杂的问题。

结构型模式区别与比较


1.桥接模式与装饰模式

这两个模式在一定程度上都是为了减少子类的数目,避免出现复杂的继承关系。但是它们解决的方法却各有不同,装饰模式把子类中比基类中多出来的部分放到单独的类里面,以适应新功能增加的需要,当我们把描述新功能的类封装到基类的对象里面时,就得到了所需要的子类对象,这些描述新功能的类通过组合可以实现很多的功能组合,装饰模式的简略图如下:

装饰模式图

桥接模式则把原来的基类的实现化细节抽象出来,在构造到一个实现化的结构中,然后再把原来的基类改造成一个抽象化的等级结构,这样就可以实现系统在多个维度上的独立变化,桥接模式的简略图如下:

桥接模式图

2.外观模式和代理模式

外观模式和代理模式解决问题的侧重点不同,但是它们解决问题的手法却是一样的,即都是引入了间接层的手法,这也是我们软件系统中经常用的一种手法。外观模式虽然侧重于简化接口,但是在某些情况下,外观模式也可以兼任代理模式的责任,例如外观对象有可能是另一个位于另一个地址空间对象的远程代理,这时候我们可以叫做外观代理模式,或者代理外观模式。它们的类简略图如下:

外观模式图

代理模式图

3.适配器模式

适配器模式重在转换接口,它能够使原本不能在一起工作的两个类一起工作,所以经常用在类库复用,代码迁移等方面,有一种亡羊补牢的味道。类适配器和对象适配器可以根据具体实际情况来选用,但一般情况建议使用对象适配器模式,如下图所示,左边是类适配器模式,右边是对象适配器模式:

对变化的封装


如何应对变化,是软件开发的一个永恒的主题,也许我们不能够杜绝变化的发生,但至少我们可以通过一些手段让变化降到最低。“找到系统可变的因素,将之封装起来”,通常就叫做对变化的封装。关于这个问题的解释在《Java与模式》中讲的很清晰,抽象化与实现化的简单实现,也就是“开-闭”原则在类层次上的最简单实现,如下图所示:

图6

在这个继承结构中,第一层是抽象化,它封装了抽象的业务逻辑,这是系统中不变的部分;第二层是实现化,它是具体的业务逻辑的实现,封装了系统中变化的部分,这个实现允许实现化角色多态性的变化:

图7

也就是说,客户端依赖的是业务逻辑的抽象化类型的对象,而与抽象化的具体实现无关,不在乎它到底是“实现化”,“实现化2”还是“实现化3”,如下图所示:

图8

每一种继承关系都封装了一个变化因素,而一个继承关系不应当处理两个变化因素,换言之,这种简单继承关系不能处理抽象化与实现化都变化的情况,如下图所示:

图9

上图中的两个变化因素应当是独立的,可以在不影响另一者的情况下独立的变化,如下面这两个等级结构分别封装了自己的变化因素,由于每一个变化因素都是可以通过静态关系表达的,因此分别使用继承关系实现,如下图:

图10

在抽象化和实现化之间的联系怎么办呢?好的设计只有一个,不好的设计却有很多中,下面这种设计就是继续使用继承进行静态关系设计的类图:

图11

这样的设计其实存在着很多的问题,首先出现的是多重的继承关系,随着具体实现化的增多,子类的继承关系会变得异常复杂;其次如果出现新的抽象化修正或者新的具体实现角色,就只好重新修改现有系统中的静态关系,以适应新的角色,这就违背了开放-封闭原则。正确是设计应该是使用两个独立的等级结构封装两个独立的变化因素,并在它们之间使用聚合关系,以达到功能复用的目的,这就回到了我们的桥接模式上,如下图所示:

图12

从另一个角度讲,一个好的设计通常没有多于两层的继承等级结构,或者说,如果出现两个以上的变化因素,就需要找出哪一个因素是静态的,可以使用静态关系,哪一个是动态的,必须使用聚合关系。

转载于:https://www.cnblogs.com/Ming8006/archive/2013/02/28/2937546.html

设计模式:结构型模式总结相关推荐

  1. 设计模式-结构型模式-装饰模式

    设计模式-结构型模式-装饰模式 栗子 以成绩单需要家长签字为要求. 成绩单类图 // 抽象成绩单 public abstract class SchoolReport{// 成绩单你的成绩情况publ ...

  2. 设计模式-结构型模式篇

    设计模式 目录: 一.代理模式 二.适配器模式 三.装饰者模式 四.桥接模式 五.外观模式 六.组合模式 七.享元模式 注:学习视频:黑马程序员Java设计模式 结构型模式 结构性模式描述如何将类或对 ...

  3. JAVA设计模式--结构型模式

    2019独角兽企业重金招聘Python工程师标准>>> 我们接着讨论设计模式,上篇文章我讲完了5种创建型模式,这章开始,我将讲下7种结构型模式:适配器模式.装饰模式.代理模式.外观模 ...

  4. 设计模式 结构型模式 外观模式(Facade Pattern)

    在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化. 这时为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 &quo ...

  5. 设计模式--结构型模式

    总体来说设计模式分为三大类:创建型模式.结构型模式和行为型模式. 博主的上一篇文章已经提到过创建型模式,此外该文章还有设计模式概况和设计模式的六大原则.设计模式的六大原则是设计模式的核心思想,详情请看 ...

  6. JAVA设计模式--结构型模式--代理模式

    1.代理模式(Proxy Pattern) 一个类代表另一个类的功能.这种类型的设计模式属于结构型模式.在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口. 1.1意图: 为其他对象提供 ...

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

    七大 - 结构型模式 汇总篇 一.适配器模式 1.基本介绍 2.代码示例 3.在springmvc中使用适配器模式 二.桥接模式 1.基本介绍 2.代码示例 3.桥接模式在JDBC的源码中使用 三.装 ...

  8. 设计模式 - 结构型模式_外观模式

    文章目录 结构型模式 概述 Case Bad Impl Better Impl 小结 结构型模式 结构型模式主要是解决如何将对象和类组装成较大的结构, 并同时保持结构的灵活和⾼效. 结构型模式包括:适 ...

  9. 设计模式——结构型模式之代理模式和适配器模式(类比+图解,从无到有,一文看懂几种模式的区别)

    设计模式 系列文章: 一.创建型模式--工厂模式 二.创建型模式--单例模式.原型模式 三.创建型模式--建造者模式 四.结构型模式--装饰者模式 五.结构型模式--代理模式.适配器模式 文章目录 设 ...

  10. 设计模式 - 结构型模式_适配器模式

    文章目录 结构型模式 概述 Case 场景模拟⼯程 Bad Impl Better Impl (适配器模式重构代码) MQ消息适配 接口适配 小结 结构型模式 结构型模式主要是解决如何将对象和类组装成 ...

最新文章

  1. 如何用12864液晶显示图片和绘制任意函数图象(打点)
  2. 【Groovy】Groovy 脚本调用 ( 命令行执行 Groovy 脚本并传入参数 | 获取 Groovy 脚本执行参数 )
  3. arch linux 安装 arm,给树莓派安装 Arch Linux ARM
  4. 在linux下实现mysql自动备份数据
  5. Exynos4412 裸机开发 —— IIC总线
  6. oracle 去除英文字母,请教:如何去掉字段中的所有标点符号(包括全角的和半角的)...
  7. Serverless 实战 —— 函数计算 + Typescript 实践
  8. proxmox换源_关于Proxmox 5.x的国内有效镜像源
  9. 数据类型转换(面试题)
  10. 用机器学习来预测情侣间何时吵架,这是一个很实用的算法
  11. latex中嵌入视频文件
  12. 华为、中兴嵌入式(C)笔试题
  13. 大数据第一季--java基础(day27)-徐培成-专题视频课程
  14. 如何缩小jpg图片大小kb?手机照片怎么压缩大小?
  15. 苹果手机如何制作铃声
  16. 有意思的互联网创业公司(Timehop/Redbeacon )
  17. MFC在两控件间画线
  18. 修改ftp更新服务器地址,修改ftp服务器地址
  19. 升级jdk版本后,出现SecurityException: JCE cannot authenticate the provider BC
  20. LoadRunner的组成

热门文章

  1. 使用 Gitee 进行代码管理(包括本地仓库如何同时关联Git和Gitee)
  2. android 触摸屏 旋转,android-使用OpenGl和触摸屏功能在视觉上纠正旋转
  3. 直播预告丨如何用 A/B 测试做好一场页面布局试验?
  4. Android•Lottie动画库填坑记
  5. 源码篇:Python 实战案例----银行系统
  6. LBS突围:从微信到微博
  7. extjs学习(关于grid)
  8. 自己动手制作(DIY)一个Mini-Linux系统
  9. windows 2008初体验常见问题: 无线网络没有正确配置为使用IP协议 错误解决办法...
  10. Performance Prism