设计模式之禅之结构类PK【装饰模式VS适配器模式】

article/2025/8/22 15:38:44

设计模式之禅PK之结构类

结构类设计模式

  • 结构类模式:
    • 适配器模式
    • 桥梁模式
    • 组合模式
    • 装饰模式
    • 门面模式
    • 享元模式
    • 代理模式
  • 相同点:他们都是通过组合类或对象产生更大的结构以适应更高的层次的逻辑需求

【装饰模式】VS【适配器模式】

  • 装饰模式和适配器模式在通用类图上没有太多的相似之处,差别比较大
  • 他们的功能上有很多【相似】的地方:
    • 都是包装作用
    • 都是通过委托方式实现其功能
  • 他们的【不同】点是:
    • 装饰包装的是自己的兄弟类,隶属于同一个家族
    • 适配器模式则修饰非血缘关系类,把一个非本家族的对象伪装成本家族的对象注意是伪装。因此本质上它还是非相同接口的对象
  • 从丑小鸭的华丽蜕变来开始
    • "话说鸭妈妈有5个孩子,其中4个孩子都是黄白相间的颜色,而最小的那只也就是叫做丑小鸭的那只,是纯白色的,与兄弟姐妹都不相同,在遭受了诸多的嘲讽和讥笑后,最终丑小鸭变成了一只美丽的天鹅"
    • 现在开始,进入丑小鸭的华丽蜕变过程吧!
装饰模式版的丑小鸭适配器模式版的丑小鸭
首先肯定丑小鸭就是一只天鹅,只是因为它从小或者是鸭妈妈的无知才没有被认出来是白天鹅,经过一段时间后,它逐步变成了一个漂亮、自信、优美的白天鹅需要从鸭妈妈的角度分析,四个鸭子都是真正的鸭子,丑小鸭实际不是鸭--“雄兔脚扑朔,雌兔眼迷离,双兔傍地走,安能辨我是雌雄”
设计:先设计一个丑小鸭,然后根据时间的先后来进行不同的美化处理--长出漂亮的羽毛--然后学会飞行--最后变成一只白天鹅设计:鸭和天鹅,然后鸭妈妈把一只天鹅看成了小鸭子,最终时间到来的时候丑小鸭变成了白天鹅

类图的比较

装饰模式适配器模式

代码详解

  • 装饰模式的丑小鸭的华丽蜕变

    • Swan

      package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public interface Swan {// 天鹅会飞public void fly();// 天鹅会叫public void cry();// 天鹅都有漂亮的外表public void desAppaearance();
      }
      
    • Uglyducking

      package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public class Uglyducking implements Swan {@Overridepublic void fly() {System.out.println("丑小鸭还比较小,还不能飞行!");}@Overridepublic void cry() {System.out.println("叫声是克鲁-克鲁-克鲁。。");}@Overridepublic void desAppaearance() {System.out.println("外形是脏兮兮的白色。毛茸茸的大脑袋!");}}
      
    • Decorator

      package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public class Decorator implements Swan {private Swan swan;public Decorator(Swan swan) {super();this.swan = swan;}@Overridepublic void fly() {swan.fly();}@Overridepublic void cry() {swan.cry();}@Overridepublic void desAppaearance() {swan.desAppaearance();}}
      
    • StrongBehavior

      package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public class StrongBehavior extends Decorator {// 强化谁public StrongBehavior(Swan swan) {super(swan);}// 会飞行了@Overridepublic void fly() {System.out.println("会飞行了!!!");}}
      
    • BeautifyAppearance

      package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public class BeautifyAppearance extends Decorator {// 要美化谁public BeautifyAppearance(Swan swan) {super(swan);}// 外表美化处理@Overridepublic void desAppaearance() {System.out.println("外表是纯色到的,非常惹人喜爱!");}}
      
    • Client

      package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public class Client {public static void main(String[] args) {System.out.println("=====很久很久以前,这里有一只丑陋的小鸭子=====");Swan ducking = new Uglyducking();// 展示一下小鸭子ducking.desAppaearance();ducking.cry();ducking.fly();// 丑小鸭终于发现自己是一只白天鹅System.out.println("=====时间过去了很久,丑小鸭长大了=====");ducking = new BeautifyAppearance(ducking);ducking.desAppaearance();ducking = new StrongBehavior(ducking);ducking.fly();}
      }
      
    • 执行结果

      =====很久很久以前,这里有一只丑陋的小鸭子=====
      外形是脏兮兮的白色。毛茸茸的大脑袋!
      叫声是克鲁-克鲁-克鲁。。
      丑小鸭还比较小,还不能飞行!
      =====时间过去了很久,丑小鸭长大了=====
      外表是纯色到的,非常惹人喜爱!
      会飞行了!!!
      
  • 适配器模式的丑小鸭的华丽蜕变

    • Duck

      package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public interface Duck {// 会叫public void cry();// 鸭子的外形public void desAppearance();// 鸭子的其他行为public void desBehavior();
      }
      
    • Ducking

      package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public class Ducking implements Duck {@Overridepublic void cry() {System.out.println("叫声是:嘎嘎~~");}@Overridepublic void desAppearance() {System.out.println("外形是黄白相间的,嘴长!");}@Overridepublic void desBehavior() {System.out.println("会游泳~");}}
      
    • Swan

      package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public interface Swan {// 天鹅会飞public void fly();// 天鹅会叫public void cry();// 天鹅都有漂亮的外表public void desAppaearance();
      }
      
    • WhiteSwan

      package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public class WhiteSwan implements Swan {@Overridepublic void fly() {System.out.println("会飞~~");}@Overridepublic void cry() {System.out.println("叫声:克鲁-克鲁");}@Overridepublic void desAppaearance() {System.out.println("外形是纯白色,惹人喜爱!");}}
      
    • UglyDucking

      package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public class UglyDucking extends WhiteSwan implements Duck {@Overridepublic void cry() {super.cry();}@Overridepublic void desAppearance() {super.desAppaearance();}@Overridepublic void desBehavior() {System.out.println("会游泳!");super.fly();}}
      
    • Client

      package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/
      public class Client {public static void main(String[] args) {// 鸭子System.out.println("鸭妈妈的四个孩子是这样的:");Duck duck = new Ducking();duck.cry();duck.desAppearance();duck.desBehavior();// 独特的丑小鸭System.out.println("丑小鸭长大后:");Duck dk = new UglyDucking();dk.cry();dk.desAppearance();dk.desBehavior();}
      }
      
    • 执行结果

      鸭妈妈的四个孩子是这样的:
      叫声是:嘎嘎~~
      外形是黄白相间的,嘴长!
      会游泳~
      丑小鸭长大后:
      叫声:克鲁-克鲁
      外形是纯白色,惹人喜爱!
      会游泳!
      会飞~~
      

最佳实践

  • 装饰模式与适配器模式的不同
不同装饰模式适配器模式
意图加强对象的功能(也可以削弱)转化(把一个天鹅当做一个鸭子来看待)
施与对象自己的同宗两个不同的对象
场景不同任何时候补救模式(项目已经完毕:紧急处理手段)
扩展性不同容易

声明

  • 摘自秦小波《设计模式之禅》第2版;
  • 仅供学习,严禁商业用途;
  • 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;

http://chatgpt.dhexx.cn/article/UoIylpH5.shtml

相关文章

设计模式之禅——观察者模式

观察者模式是一种比较常见的设计模式,在安卓源码中也应用得很多,如baseAdapter、相关触发器机制。 首先从一个情景入手,战国时期,李斯(观察者)作为秦国宰相希望监视(观察)韩非子&…

《设计模式之禅》-策略模式

策略模式 定义 定义一组算法,将每个算法都封装起来,并且使它们之间可以互换 策略模式有三个角色 1.Strategy 抽象策略角色 策略,算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。 2.Concrete…

《设计模式之禅》-原型模式

原型模式属于比较简单的设计模式,所以使用次数也非常的多 定义: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 原型模式的通用代码: public class PrototypeClass implements Cloneable {Overridepublic Pr…

设计模式之禅——门面模式

门面模式【Facade Pattern】也叫外观模式,是一种比较常用的封装模式,其定义如下: 【要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更容易使用】 门面模式注重“统一…

设计模式之禅读后感

过早优化是万恶之源——Unix编程思想 让正确的程序更快,要比让快速的程序正确容易得多。 文章目录 前言六大设计原则*单一职责原则**里氏替换原则**依赖倒置原则**接口隔离原则**迪米特法则**开闭原则* 二十三种设计模式创建型模式*单例模式**工厂方法模式**抽象工厂…

设计模式之禅笔记

设计模式PK 创建类模式PK 工厂方法模式 VS 建造者模式 工厂方法模式注重的是整体对象的创建方法。建造者模式注重的是部件构建的过程。 工厂方法模式的对象粒度较粗,建造者模式的产品对象粒度较细。 抽象工厂模式 VS 建造者模式 抽象工厂模式也是注重产品的整…

《设计模式之禅》(第2版)

第一部分 大旗不挥 谁敢冲锋 —— 6大设计原则全新解读 第1章 单一职责原则 单一职责原则,Single Responsibility Principle,简称SRP,有且只有一个原因引起类/接口的变更;即一个接口/类只有一个职责,只负责一件事…

设计模式之禅《一》 大旗不挥,谁敢冲锋 ——6大设计原则

设计模式之禅《一》大旗不挥,谁敢冲锋 ——6大设计原则 《一》 六大原则 一:单一职责原则 1、单一职责原则最难划分的就是职责 2、有两个可以变化的原因放到了一个接口中,这就为以后的变化带来了风险。 3、对于单一职责原则,…

设计模式之禅(六大设计原则)

1.单一职责原则(Single Responsibility Principle) 也就是职责划分要明确,单一职责原则提出了一个编写程序的标准,用“职责”或者“变化原因”来衡量接口或者类设计的是否优良,但是“职责”或者“变化原因”都是不可度量的,因项目…

什么是ASCII码

ASCII码英文全称America Standard Code for Information Interchange,中文意思:美国信息交换标准码。它已被国际标准化组织(ISO)定为国际标准,称为ISO 646标准。适用于所有拉丁文字字母,ASCII码有7位码和8位…

最全ASCii 码表和说明

A的ASCII码是65,a的ASCII码是97。 ASCII码表中,小写字母排在大写字母的后面,一个字母的大小写数值相差32,一般知道大写字母的ASCII码数值,其对应的小写字母的ASCII码数值就算出来了,是大写字母的ASCII码数…

ASCII码

字符编码即ASCII码(American Standard Code for Information Interchange,美国信息交换标准码,国际通用的计算机内的字符数字的二进制编码),它是7位二进制编码,总共有128个符号,包括英文26个大写字母&#…

什么叫ASCII码

一个字符A,以 字符和整型都可以输出。因为字符A也是以二进制存储,这个二进制对应一个整数 那究竟什么是ASCII码? ASCII不是一个值,而是一种规定。 ASCII规定了不同字符是使用哪个整数值表示 它规定: A --65 B --…

关于ASCII码的转换

目录 ASCII码表ASCII码与字符之间的转换 ASCII码表 ASCII码与字符之间的转换 python中chr()和ord()两个函数可以实现ASCII码与字符之间的转换, 两者之间的关系 转换举例 stringbsuahisas num_list[ord(i) for i in string] str_list[chr(i) for i in num_list] p…

ASCII码介绍

ASCII码 概念 ASCII(American Standard Code for Information Interchange)的缩写(美国标准信息交换代码),已被国际标准化组织ISO采纳,作为国际通用的信息交换标准代码。 诞生背景 计算机对数据的识别、运算和存储都建立在二进制…

ASCII编码

ASCII编码 ASCII编码的概念对控制字符的解释详细说明 ASCII编码的概念 计算机是以二进制的形式来存储数据的,它只认识 0 和 1 两个数字,我们在屏幕上看到的文字,在存储之前都被转换成了二进制(0和1序列),在…

ascii码a和A为什么差32而不是26

ascii码a和A为什么差32而不是26? A的ASCII码是65,a的ASCII码是97; ASCII码表中,一个字母的大小写数值相差32,一般知道大写字母的ASCII码数值,其对应的小写字母的ASCII码数值就算出来了,是大写字…

ASCII码详解

ASCII简介 ASCII 码使用指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符。标准 ASCII 码也叫基础ASCII码,使用 7 位二进制数来表示所有的大写和小写字母,数字 0 到 9、标点符号, 以及在美式英语中使用的特殊控制字符。其中&a…

a到z的ascii码值是多少_a和A对应的ASCII码数值分别是多少啊?

展开全部 A的ASCII码是65,a的ASCII码是97。 ASCII码表中,小写字母32313133353236313431303231363533e78988e69d8331333366303066排在大写字母的后面,一个字母的大小写数值相差32,一般知道大写字母的ASCII码数值,其对应…

输出ASCII码

输出字符的ASCII码 从键盘输入一个字符&#xff0c;按规定格式输出这个字符及它的ASCII码。例如&#xff1a; 输入 A 输出 “The ASCII of A is 65”.//输出的数值在双引号以内// 代码&#xff1a; ​ #include <stdio.h>int main() {char a;scanf("…