【设计模式深度剖析】【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.mzph.cn/pingmian/20432.shtml

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

相关文章

jmeter性能测试用例提取

性能测试用例提取参考(根据单、混合场景、模块、运行时间、优先级)去考虑 Tips:用例提取和用例设计不一样 后期可以结合性能测试用例设计(设置线程数、时间、循环、同步定时器等等)来做性能测试

K210视觉识别模块学习笔记4: 训练与使用自己的模型_识别字母

今日开始学习K210视觉识别模块: 模型训练与使用_识别字母 亚博智能的K210视觉识别模块...... 固件库: maixpy_v0.6.2_52_gb1a1c5c5d_minimum_with_ide_support.bin 文章提供测试代码讲解、完整代码贴出、测试效果图、测试工程下载 这里也算是正式开始进入到视觉识别的领域了…

通信网优:薪资从3k-20k究竟要多久?

随着华为中标结果的不断公布,通信网优行业有了新变化。各大通信公司关于今年的网优业务市场份额也陆续公布,从目前的中标结果来看 杭州东信网络技术有限公司和南京嘉环科技股份有限公司并列排名第一,信科通信科技有限公司排名第三。而北京电旗…

ABP框架+Mysql(三)

创建,更新和删除图书 创建新书籍 创建 modal form 在 Acme.BookStore.Web 项目的 Pages/Books 目录下新建一个 CreateModal.cshtml Razor页面: CreateModal.cshtml.cs 打开 CreateModal.cshtml.cs 代码文件(CreateModalModel 类),替换成以下代码: using System.Threading.…

【贪心算法题目练习】

1. 分发饼干 这道题目和我们之前讲到的田忌赛马的问题很相似,只不过这这里不需要劣等马去抵消掉优等马,直接上贪心策略: 先将两个数组排序。针对胃口较小的孩子,从小到大挑选饼干: i. 如果当前饼干能满足,直接喂(最小…

Flutter开发效率提升1000%,Flutter Quick教程之对组件进行拖拽与接收

1,首先,所有可以选择的组件,都在左边的组件面板里。从里面点击任何一个,按住左键,向右边的手机面板上进行拖拽即可。 2,拖拽后,我们要选择一个接收组件。什么时候可以接收组件,就是当…

龙叔Linux:别名(alias)

在Linux中,别名(alias)是一个命令的简短形式,通常用于简化或替换更长的命令序列。你可以使用alias命令来创建、查看和删除别名,定制自己专属的命令。一、创建别名 1.1、临时创建 你可以使用alias命令在命令行中直接定…

B-TREE教程(个人总结版)

背景 在计算机科学中,数据存储和检索的效率是一个重要的研究课题。B-树(B-Tree)作为一种自平衡树结构,特别适合于在磁盘存储中处理大规模数据。它通过保持树的高度平衡,使得搜索、插入和删除操作的时间复杂度保持在对…

docker部署Minio对象存储及使用

1.拉取镜像 docker pull minio/minio2.创建数据目录 mkdir -p /data/minio/data3.启动容器 docker run -p 39000:9000 -p 39090:9090 \ --name minio \ -d --restartalways \ -e "MINIO_ACCESS_KEYjyadmin" \ -e "MINIO_SECRET_KEYjyzx2023" \ -v /data…

沃通CA根证书获数科网维《商用密码根证书授信证明》

近日,沃通CA三款根证书获数科网维《商用密码根证书授信证明》,将列入数科受信根证书列表并预置到数科文档阅读器。这标志着沃通CA国产化适配能力进一步提升,沃通国产文档签名证书与数科国产文档阅读器兼容互认,能够更好地响应政企…

Nginx编译安装,信号,升级nginx

编译安装nginx:前面博客有写编译安装过程 systemctl stop firewalld setenforce 0 mkdir /data cd /data wget http://nginx.org/download/nginx-1.18.0.tar.gz tar xf nginx-1.18.0.tar.gz cd nginx-1.18.0/ yum -y install make gcc pcre-devel openssl-devel …

揭秘:Java字符串对象的内存分布原理

先来看看下面寄到关于String的真实面试题,看看你废不废? String str1 "Hello"; String str2 "Hello"; String str3 new String("Hello"); String str4 new String("Hello");System.out.println(str1 str2)…

Android 11 Audio strategy配置解析

在启动AudioPolicyService时,通过EngineBase的loadAudioPolicyEngineConfig函数去解析strategy配置。其调用流程如下 接下来就对loadAudioPolicyEngineConfig展开分析 1,解析volume标签 engineConfig::ParsingResult EngineBase::loadAudioPolicyEngine…

Pytorch Lighting 库的学习 mvsplat 的笔记

变量理解: context_image: 表示投影的 refrence image Epipolar Transformer vs Swin Transformer : 不同于 Pixel Splat 使用的是 Epipolar Transformer. MVspalt 使用的是 Swin Transformer, 但是作者在 Code 里面 也使用了 Epipolar Tran…

容器项目之前后端分离

容器化部署ruoyi项目 #需要的镜像nginx、java、mysql、redis、 #导入maven镜像、Java镜像和node镜像 docker load -i java-8u111-jdk.tar docker load -i maven-3.8.8-sapmachine-11.tar docker load -i node-18.20.3-alpine3.20.tar #拉取MySQL和nginx镜像 docker pull mysql…

echarts学习:基本使用和组件封装

前言 我在工作中使用echarts较少,这就导致每次使用时都要从头再来,这让我很头疼。因此我决心编写一系列文章将我参与工作后几次使用echarts所用到的知识记录下来,以便将来可以快速查阅。 一、基本使用 像我一样的新手,想要入门e…

【Java】还有人不懂继承?25 个 Case 包教包会

还有人不懂继承?25 个 Case 包教包会 1.Implement single inheritance2.Implement multilevel inheritance3.Implement hierarchical inheritance4.Override a base class method into a derived class5.Demonstrate the protected access specifier6.Create an Stu…

《面试笔记》——MySQL终结篇30

三大范式? 第一范式:字段具有原子性,不可再分(字段单一职责) 第二范式:满足第一范式,每行应该被唯一区分,加一列存放每行的唯一标识符,称为主键(都要依赖主…

10- Redis 键值对数据库是怎么实现的?

在开始将数据结构之前,先给介绍下 Redis 是怎样实现键值对(key-value)数据库的。 Redis 的键值对中的 key 就是字符串对象,而 value 可以是字符串对象,也可以是集合数据类型的对象,比如 List 对象&#xf…

Django序列化器中is_valid和validate

今天上班的时候分配了一个任务,是修复前端的一个提示优化,如下图所示: 按照以往的经验我以为可以直接在validate上进行校验,如何抛出一个异常即可 ,例如: class CcmSerializer(serializers.ModelSerialize…