【设计模式深度剖析】【B】【结构型】【对比】| 主要区别包装的不同

👈️上一篇:享元模式

回 顾:结构型设计模式

1.代理模式👈️

2.装饰器模式👈️

3.适配器模式👈️

4.组合模式👈️

5.桥接模式👈️

6.外观模式👈️

7.享元模式👈️

设计模式-专栏👈️

文章目录

  • 结构型模式对比
  • 概览
  • 代理模式
    • 明星接口IStar:上层抽象主题
    • 明星类Star:主题类,实现上层抽象
    • 经纪人代理人Proxy
    • 测试
  • 装饰模式
    • 明星接口IStar:上层抽象构件
    • 明星类Star的代码
    • 替身演员Standin(被装饰类角色)
    • 抽象装饰类Decorator
    • 具体装饰类ConcreteDecorator
    • 测试类:演员演戏,以及被装饰的替身演戏
  • 适配器模式
    • 明星接口IStar:目标(Target)角色
    • 适配器的代码Adapter:将替身演员(源角色) 适配到 明星接口(目标接口)
    • 替身演员Standin:源(Adaptee)角色
    • 演员接口IActor:替身演员(源角色)上层抽象接口
    • 测试类:明星自己演戏 && 适配的替身演员演戏
  • 参考

结构型模式对比

结构类模式包括:代理模式装饰模式适配器(变压器)模式组合模式桥梁模式门面(外观)模式享元模式,它们都是通过组合类或对象产生更复杂的结构以适应更高层次的逻辑需求

其中:

  1. 组合模式、桥梁模式、外观模式、享元模式有各自显著特点,易区分

    • 组合模式(Composite Pattern)注重形成上下层次间的“树形结构”

    • 桥接模式(Bridge Pattern)主要注重的是解耦抽象与实现,使得它们可以独立地变化。

      通过引入抽象层与实现层的概念,并利用组合关系来解耦抽象与实现。它使得抽象层与实现层可以独立地变化,提高了系统的灵活性和扩展性。在需要频繁地修改或扩展系统时,桥梁模式是一种非常有效的设计模式。

    • 外观模式(Facade Pattern)提供了一种统一的接口,用于简化对复杂子系统的访问,隐藏子系统的细节,使得客户端只需与外观对象交互,而无需与子系统中的多个对象交互。

    • 享元模式(Flyweight Pattern)是池技术实现的重要方式,系统内有此对象就返回该对象的引用,否则创建该对象

  2. 主要对代理模式(Proxy Pattern)、装饰模式(Decorator Pattern)和适配器模式(Adapter Pattern)进行对比,这三个模式有一个共同点,它们都能够对类进行“包装”wrapping ),但它们之间的主要区别如下

    • 装饰模式是代理模式的一个特殊应用,虽然它们都具有相同的接口,但装饰模式是对类的功能进行加强或减弱,重点是类的功能变化;而代理模式着重代理过程的控制
    • 装饰模式和适配器模式都能对类进行“包装”,但装饰模式包装的是同一家族(相同接口或父类)的对象,而适配器模式可以修饰不同接口的对象,主要是将非本家族的对象伪装成同一家族对象。
      • [记]
      • 【代理模式】中,客户端需要创建被代理对象(主题类),创建代理类并注入主题类,从而持有被代理对象,进行附加业务逻辑处理;
        • 代理类通过组合方式组合上层抽象接口到类中,构造函数实际上用于注入主题类,从而使得代理类持有主题类;
      • 【装饰模式】装饰“本家”,【适配器模式】将不是“本家”的类伪装成“本家”的,达到适配效果。
      • 具体装饰类构造注入被装饰类,调用抽象装饰父类构造器,传给抽象父类被装饰类。从而,使得抽象装饰父类持有被装饰对象;
      • 【适配逻辑】:定义适配器类继承源(Adaptee)角色(Standin类)实现目标(Target)接口(IStar接口);从而使得适配器类中将源角色中的方法“移花接木”到实现的目标接口的方法中(用得到super调用源角色方法)

概览

  • 代理模式
    • 通过经纪人安排明星是否接拍戏、拍广告代言的示例来说明
  • 装饰模式
    • 通过替身演员被装饰“看上去就像演员本身”去演戏来说明
  • 适配器模式
    • 通过对替身演员类进行适配到明星接口

代理模式

现在很多明星都有经纪人,所有的业务都是通过经纪人进行联络和活动,这是典型的代理模式。

下述内容用于实现任务描述:使用代理模式演示经纪人对明星的代理活动

经纪人代理明星,安排是否拍戏,是否广告代言,类图如下:

在这里插入图片描述

明星接口IStar:上层抽象主题

public interface IStar {// 明星演戏public abstract void action();// 明星广告代言public abstract void adver();
}

明星类Star:主题类,实现上层抽象

public class Star implements IStar {// 姓名private String name;// 构造函数public Star(String name) {this.name = name;}@Overridepublic void action() {System.out.println(this.name + "在演戏中");}@Overridepublic void adver() {System.out.println(this.name + "在做广告代言");}
}

经纪人代理人Proxy

代理角色类,实现上层抽象,同时将上层抽象(实际注入主题类即被代理类)组合(是一种强聚合关系,代表部分与整体关系)到本类中

public class Proxy implements IStar {private IStar star;// 构造注入上层抽象类型的对象public Proxy(IStar star) {this.star = star;}// 代理明星演戏@Overridepublic void action() {Random random = new Random();if (random.nextBoolean()) {System.out.println("经纪人同意安排明星演戏");this.star.action();} else {System.out.println("明星档期已满,不能安排演戏");}}@Overridepublic void adver() {Random random = new Random();if (random.nextBoolean()) {System.out.println("经纪人同意安排明星广告代言");this.star.adver();} else {System.out.println("明星档期已满,不能安排广告代言");}}
}

测试

经纪人代理明星,安排是否拍戏,是否广告代言

public class StarProxyTest {public static void main(String[] args) {// 定义一个明星IStar star = new Star("范冰冰");// 定义一个经纪人Proxy proxy = new Proxy(star);// 代理安排演戏否proxy.action();// 代理安排广告代言否proxy.adver();}
}------
经纪人同意安排明星演戏
范冰冰在演戏中
明星档期已满,不能安排广告代言

装饰模式

现在很多明星在演戏时都使用替身,其实就是将替身进行修饰,使观众以为是明星自己演戏

下述内容用于实现任务描述:使用装饰模式将替身演员修饰成明星.

替身演员被装饰达到去替代演员演戏的效果,类图如下:

在这里插入图片描述

明星接口IStar:上层抽象构件

将主题类方法进行抽象,用于被装饰类也实现此接口,从而被具体装饰类所装饰

public interface IStar {// 明星演戏public abstract void action(String context);
}

明星类Star的代码

public class Star implements IStar {@Overridepublic void action(String context) {System.out.println("------------");System.out.println("明星亲自演戏" + context);System.out.println("------------");}
}

替身演员Standin(被装饰类角色)

public class Standin implements IStar {@Overridepublic void action(String context) {System.out.println("替身演戏" + context);}
}

抽象装饰类Decorator

public abstract class Decorator implements IStar {private IStar star;protected Decorator(IStar star) {this.star = star;}@Overridepublic void action(String context) {this.star.action(context);}
}

具体装饰类ConcreteDecorator

public class ConcreteDecorator extends Decorator {// 构造注入被装饰类,调用抽象装饰父类构造器,传给抽象父类被装饰类。// 从而,使得抽象装饰父类持有被装饰对象public ConcreteDecorator(IStar star) {super(star);}@Overridepublic void action(String context) {System.out.println("------------");//添加具体修饰逻辑System.out.println("进行化妆、造型,让人看上去像明星");super.action(context);System.out.println("------------");}
}

测试类:演员演戏,以及被装饰的替身演戏

public class DecoratorTest {public static void main(String[] args) {// 明星自己演戏IStar star = new Star();star.action("表演10分钟");//在找替身演员替演IStar standin = new Standin();standin = new ConcreteDecorator(standin);standin.action("表演5分钟");}
}------------
明星亲自演戏表演10分钟
------------
------------
进行化妆、造型,让人看上去像明星
替身演戏表演5分钟
------------

[注意]:Star和Standin都继承IStar接口,Decorator装饰类是对同一家族的类进行修饰

适配器模式

下述内容用于实现任务描述:使用适配器模式演示替身演员和明星

此示例适配器角色用于把替身演员类适配到明星上层抽象接口。类图如下:

在这里插入图片描述

适配逻辑:定义适配器类继承源(Adaptee)角色(Standin类)实现目标(Target)接口(IStar接口);从而使得适配器类中将源角色中的方法“移花接木”到实现的目标接口的方法中(用得到super调用源角色方法)

明星接口IStar:目标(Target)角色

public interface IStar {// 明星演戏public abstract void action(String context);
}

明星类Star的代码

public class Star implements IStar {@Overridepublic void action(String context) {System.out.println("明星亲自演戏" + context);}
}

适配器的代码Adapter:将替身演员(源角色) 适配到 明星接口(目标接口)

public class Adapter extends Standin implements IStar {@Overridepublic void action(String context) {// 让替身演员演戏super.play(context);}
}

替身演员Standin:源(Adaptee)角色

public class Standin implements IActor {@Overridepublic void play(String context) {// 替身演员演戏System.out.println("替身演戏" + context);}
}

演员接口IActor:替身演员(源角色)上层抽象接口

public interface IActor {// 演员演戏public abstract void play(String context);
}

测试类:明星自己演戏 && 适配的替身演员演戏

public class TestAdapter {public static void main(String[] args) {IStar star = new Star();star.action("表演10分钟");// 再找替身演员替演star = new Adapter();star.action("表演5分钟");}
}------明星亲自演戏表演10分钟
替身演戏表演5分钟

[注意] Star和Standin分别继承不同的接口,Adapter适配器可以对不同类型的类进行包装

参考

《设计模式(Java版)韩敬海主编》


👈️上一篇:享元模式

回 顾:结构型设计模式

1.代理模式👈️

2.装饰器模式👈️

3.适配器模式👈️

4.组合模式👈️

5.桥接模式👈️

6.外观模式👈️

7.享元模式👈️

设计模式-专栏👈️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/337958.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【EFK日志系统】docker一键部署kibana、es-head

docker一键部署kibana、es-head kibana部署es-head部署 上一篇文章搭建了es集群 规划服务器是 es01:172.23.165.185 es02:172.23.165.186 es03:172.23.165.187 那么kibana就搭建在主节点es01:172.23.165.185 按照顺序参考: docker一键部署EFK系统(elas…

洗地机什么牌子好?洗地机前十名排行榜

现代吸拖扫一体洗地机不仅高效,还具有智能化设计,使清洁变得轻松。它强大的吸尘功能能够轻松应对灰尘和碎屑,不论是硬质地面还是地毯,都能提供理想的清洁效果。配合拖地功能,通过内置水箱和智能拖布,能彻底…

代码随想录-Day25

216.组合总和III 找出所有相加之和为 n 的 k 个数的组合,且满足下列条件: 只使用数字1到9 每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。 示例 1: 输入: k 3, n 7 输…

C语言 | Leetcode C语言题解之第120题三角形最小路径和

题目&#xff1a; 题解&#xff1a; int minimumTotal(int** triangle, int triangleSize, int* triangleColSize) {int f[triangleSize];memset(f, 0, sizeof(f));f[0] triangle[0][0];for (int i 1; i < triangleSize; i) {f[i] f[i - 1] triangle[i][i];for (int j …

Redis数据类型(上篇)

前提&#xff1a;&#xff08;key代表键&#xff09; Redis常用的命令 命令作用keys *查看当前库所有的keyexists key判断某个key是否存在type key查看key是什么类型del key 删除指定的keyunlink key非阻塞删除&#xff0c;仅仅将keys从keyspace元数据中删除&#xff0c;真正的…

如何获取SSL证书,消除网站不安全警告

获取SSL证书通常涉及以下几个步骤&#xff1a; 选择证书颁发机构&#xff08;CA&#xff09;&#xff1a; 你需要从受信任的SSL证书颁发机构中选择一个&#xff0c;比如DigiCert、GlobalSign、JoySSL等。部分云服务商如阿里云、腾讯云也提供免费或付费的SSL证书服务。 生成证…

电子烟开发【恒压、恒有效算法】

恒压算法 pwm是通过软件模拟的 pwm满值运行是250全占空比 #define D_TARGET_AVERAGE_VOLTAGE 3500 //R_ADC1_Vout &#xff1a;发热丝两端AD值 //R_ADC_FVR &#xff1a;电池电压AD值 //FVR_VOLTAGE &#xff1a;电池AD参考电压 满电值AD //R_Smk1Duty &#xff1a;最后…

uniapp创建支付密码实现(初始密码,第二次密码)

示例&#xff1a; 插件地址&#xff1a;自定义数字/身份证/密码输入框&#xff0c;键盘密码框可分离使 - DCloud 插件市场 1.下载插件并导入HBuilderX&#xff0c;找到文件夹&#xff0c;copy number-keyboard.vue一份为number-keyboard2.vue&#xff08;number-keyboard.vue是…

详细介绍运算符重载函数,清晰明了

祝各位六一快乐~ 前言 1.为什么要进行运算符重载&#xff1f; C中预定义的运算符的操作对象只能是基本数据类型。但实际上&#xff0c;对于许多用户自定义类型&#xff08;例如类&#xff09;&#xff0c;也需要类似的运算操作。这时就必须在C中重新定义这些运算符&#xff…

Centos 7 安装刻录至硬件服务器

前言 在日常测试中&#xff0c;会遇到很多安装的场景&#xff0c;今天给大家讲一下centos 7 的安装&#xff0c;希望对大家有所帮助。 一.下载镜像 地址如下&#xff1a; centos官方镜像下载地址https://www.centos.org/download/ 按照需求依次点击下载 二.镜像刻录 镜像刻…

C++语言·list链表(下)

还是之前说的&#xff0c;因为要写模板&#xff0c;为了避免链接出现问题&#xff0c;我们将所有内容都写到一个文件中去。首先就是画出链表的框架 链表本身只需要一个头节点就足以找到整条链表&#xff0c;而需要它拼接的节点我们再写一个模板。而我们知道list是一个带头双向循…

微信小程序对接发货功能

注&#xff1a;微信小程序对接发货功能 文档地址&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html php代码 common.php use think\Config; use think\Db; use fast\Http; us…

OrangePi AIpro 变身 Android 打包机

主板基本信息介绍 OrangePi AIpro&#xff0c;是香橙派联合华为精心打造&#xff0c;建设人工智能新生态而设计的一款开发板&#xff0c;这次为大家分享下我上手的这款 OrangePi AIpro 8GB&#xff08;算力达8TOPS&#xff09; 的一些小小的经验。 基本参数如下&#xff1a; …

【Keil 5】Keil 5下载安装激活到2032年(含MDK、C51、STM32单片机)+附带百度网盘链接

这里写目录标题 安装包、激活文件下载1.双击mdk 514开始安装2.一路点next&#xff0c;信息随便写即可3.激活4.安装STM325.激活c51 安装包、激活文件下载 解压密码&#xff1a;lantongxue 链接&#xff1a;https://pan.baidu.com/s/15Aukt0j1HCFyHBE6whuDeg?pwdsjyh 提取码&…

FreeRtos进阶——中断的内部逻辑

中断与非中断API的区别 BaseType_t xQueueSendToBack(QueueHandle_t xQueue,const void *pvItemToQueue,TickType_t xTicksToWait); BaseType_t xQueueSendToBackFromISR(QueueHandle_t xQueue,const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWok…

OceanBase 内存研究(OceanBase 3.2.4.5)

内存结构 从官网的结构图可以看出&#xff0c;一台observer可使用的总内存(memory_limit)包括 系统内存(system_memory) 和 租户内存(sys租户与普通租户) 系统内存 系统内存system_memory 属于 observer 的内部内存&#xff0c;允许其它租户共享使用该内存资源 (root10.0.0.…

丛林生存法则其实就两个字:输出

不管你是在上班&#xff0c;还是在灵活就业&#xff0c;现在的大环境下&#xff0c;你要想活下来&#xff0c;生存下去&#xff0c;一定要记住这两个字&#xff1a;输出。如果你能记住更多的字&#xff0c;那便是持续高水平的输出。 你如果是大厂程序员&#xff0c;你肯定发现…

window安装ffmpeg播放本地摄像头视频

1、安装ffmpeg ffmpeg官方网站&#xff1a;FFmpeg 下载后解压文件夹名为ffmpeg 2、设置环境变量 目录 1、安装ffmpeg 设置环境变量 以F:\software\after\ffmpeg\bin为例 在命令行中输入ffmpeg出现下方代表安装成功 3、通过ffmpeg播放本地电脑摄像头 鼠标右击开始按钮&…

快速排序详讲(两种方法)

目录 原理 实现方式 正常实现 理由 先从右到左&#xff0c;在从左到右 先从左到右&#xff0c;先从右到左 挖坑法 效率 优化 测试 代码 原理 快速排序是将最左侧的数字当作关键数字&#xff0c;将关键数字放在对应位置&#xff0c;且关键数字左侧均大于它&#xff…

Spring Boot 开发 -- 过滤器与拦截器详解

引言 在Web开发中&#xff0c;经常需要对请求进行预处理或在响应后进行后处理&#xff0c;Spring Boot提供了过滤器和拦截器两种机制来实现这一需求。虽然它们都可以用来处理HTTP请求和响应&#xff0c;但在使用场景、执行顺序和配置方式上存在明显的差异。本文将详细讲解Spri…