结构设计模式 -装饰器设计模式 - JAVA

news2024/11/15 16:01:20

装饰器设计模式

    • 一. 介绍
    • 二. 代码示例
      • 2.1 抽象构件(Component)角色
      • 2.2 具体构件(Concrete Component)角色
      • 2.3 装饰(Decorator)角色
      • 2.4 具体装饰(Concrete Decorator)角色
      • 2.5 测试 结果
    • 三. 结论
      • 3.1 优缺点
      • 3.2 使用场景

前言
这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。

作者:神的孩子都在歌唱

一. 介绍

百度百科装饰模式指的是在不必改变原类文件使用继承的情况下,动态扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象

个人理解: java在编译完成后,我们无法动态的去为一个编译好的对象新增或者修改某个功能,这时候就可以通过装饰模式去设计

举例理解: 通常我们使用继承或者组合去扩展对象的行为,假如我们想要实现不同种类的手链,我们创建一个手链(Bracelet)接口,然后我们通过实现这个接口获取一个基本的手链(basic bracelet),我们可以在基本的手链的基础上进行扩展获得**金手链(Gold)和银手链(Silver)**结构图如下所示。

请添加图片描述

通过以上案例我们可以了解到,一些简单的扩展通过继承的方式就可以解决了,但如果我们还想在扩展,想要获取一个同时具备金色和银色的手链,并且还要添加某些功能,那么就会变得很复杂。如果手链类型增加,使用继承的实现逻辑就很难管理。这时候就可以通过装饰模式去设计

好了,上面的介绍都是再讲为什么要使用装饰模式,接下来就通过代码案例讲解装饰模式是怎么样子实现的,如何解决上面所说的问题

装饰模式有以下角色:

(1)抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。

(2)具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。

(3)装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。

(4)具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。

二. 代码示例

装饰模式代码具体流程如下

请添加图片描述

2.1 抽象构件(Component)角色

定义要实现的方法的接口或抽象类

/**
 * @author chenyunzhi
 * @date 2024/6/3 16:06
 * @Description 手链
 */
public interface Bracelet {

    void color();

}

2.2 具体构件(Concrete Component)角色

/**
 * @author chenyunzhi
 * @date 2024/6/3 16:08
 * @Description 基本的手链,也就是白色
 */
public class BasicBracelet implements Bracelet{
    @Override
    public void color() {
        System.out.print("基本的白色手链");
    }
}

2.3 装饰(Decorator)角色

/**
 * @author chenyunzhi
 * @date 2024/6/3 16:23
 * @Description 手链装饰器
 */
public class BraceletDecorator implements Bracelet {

    /**
     * 装饰器类应该可以访问组件变量,因此我们将保护该变量
     */
    protected Bracelet bracelet;

    public BraceletDecorator(Bracelet bracelet) {
        this.bracelet = bracelet;
    }

    @Override
    public void color() {
        this.bracelet.color();
    }
}

2.4 具体装饰(Concrete Decorator)角色

金手链

/**
 * @author chenyunzhi
 * @date 2024/6/3 16:32
 * @Description 金手链
 */
public class GoldBracelet extends BraceletDecorator{
    public GoldBracelet(Bracelet bracelet) {
        super(bracelet);
    }

    @Override
    public void color() {
        super.color();
        System.out.print(",增加金色");
    }
}

银手链

/**
 * @author chenyunzhi
 * @date 2024/6/3 16:37
 * @Description 银手链
 */
public class SilverBracelet extends BraceletDecorator{
    public SilverBracelet(Bracelet bracelet) {
        super(bracelet);
    }

    @Override
    public void color() {
        super.color();
        System.out.print(",增加银色");
    }
}

2.5 测试 结果

/**
 * @author chenyunzhi
 * @date 2024/6/3 14:39
 * @Description
 */
public class DecoratorPatternTest {
    public static void main(String[] args) throws Exception{

        // 获取金手链对象
        Bracelet goldBracelet = new GoldBracelet(new BasicBracelet());
        goldBracelet.color();

        System.out.println("\n-----------------------");

        // 获取银手链对象
        Bracelet silverBracelet = new SilverBracelet(new BasicBracelet());
        silverBracelet.color();

        System.out.println("\n-----------------------");

        // 获取包含金色和银色的手链
        Bracelet goldSilverBracelet = new GoldBracelet(new SilverBracelet(new BasicBracelet()));
        goldSilverBracelet.color();
    }
}

请添加图片描述

通过以上结果我们可以看到,如果我们想要获取包含 金色和银色的手链,可以通过组合金色和银色的装饰者对象来获取具有金色和银色手链。

三. 结论

3.1 优缺点

优点:

  • 装饰器设计模式有助于提供运行时修改能力,因此更加灵活。当选择数量较多时,易于维护和扩展。
  • 装饰器设计模式的缺点是它使用了很多相似类型的对象(装饰器)。
  • Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
  • 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点

  • 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
  • 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
  • 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

3.2 使用场景

  • 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。

    不能采用继承的情况主要有两类:

    • 第一类是系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;
    • 第二类是因为类定义不能继承(如final类)
  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

  • 当对象的功能要求可以动态地添加,也可以再动态地撤销时。

  • 装饰器模式在Java IO类中被大量使用,例如FileReader、BufferedReader等。

作者:神的孩子都在歌唱

本人博客:https://blog.csdn.net/weixin_46654114

转载说明:务必注明来源,附带本人博客连接。

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

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

相关文章

mysql 报 ERROR 1273: Unknown collation: ‘utf8mb4_0900_ai_ci‘ 的处理

1、数据库sql是mysql8的导出的,本机上安装的还是5.7的版本,然后导入sql,直接就报错。 2、mysql的下载地址: MySQL :: Download MySQL Community Server 3、报错截图: 4、重新选择一个collation就可以了,…

MoNA:复用跨模态预训练模型,少样本模态的福音 | ICML‘24

跨模态转移旨在利用大型预训练模型来完成可能不属于预训练数据模态的任务。现有的研究在将经典微调扩展到跨模态场景方面取得了一定的成功,但仍然缺乏对模态差距对转移的影响的理解。在这项工作中,进行了一系列关于转移过程中源表示质量的实验&#xff0…

最新视频号名字使用规范你了解了吗!

文章来源:视频号官方平台 视频号名字使用需遵循以下规范: 账号名字应当与简介的内容相符,且不得与已注册成功的账号名字重复。 账号超过180天未以视频号身份进行发表、评论等操作,将不再受到名字唯一保护,有其他用户申…

FPGA实现频率、幅度、相位可调的DDS以及DDS Compiler IP核的使用验证

文章目录 一、DDS介绍二、DDS原理2.1 频率计算2.2 相位改变2.3 波形切换 三、Matlab生成波形文件四、FPGA实现DDS4.1 Verilog代码4.2 仿真验证4.2.1 改变频率4.2.2 切换波形4.2.3 相位调节4.2.4 幅度调节 五、Xilinx DDS Compiler的使用5.1 功能框图5.1.1 相位累加器5.1.2 SIN/…

通俗讲解javascript的实例对象、原型对象和构造函数以及它们之间的关系

今天通俗讲解一下js的对象,因为要通俗,所以可能描述不甚准确。 在js中,想要创建一个对象,首先要写出构造函数(跟其它的语言不太一样哦,其它语言一般都会先写一个class 类名)。 构造函数写法如…

【PGCCC】 复合索引和部分索引,竟然能让查询速度提升 275 倍!

索引对于加速数据库查询和提高 PostgreSQL 应用程序的性能至关重要。但是,并非所有索引都以相同的方式发挥作用。复合索引和部分索引是两种常见类型,每种类型都有不同的用途和对性能的影响。本文我们将深入探讨复合索引和部分索引是什么、它们如何运作以…

关于在vue2中给el-input等输入框的placeholder加样式

::v-deep {.el-input--medium,.el-input__inner {height: 100%;background: #163670;border: 1px solid #4cc0f6;border-radius: 6px 6px 6px 6px;&::placeholder {color: #13EFFF;}} } 效果如下: .el-date-editor .el-range-input{&::placeholder {color:…

SAP MIGO M7146不支持移动原因

移动类型 Z91 查看配置:Z91 匹配的原因没有921 倒是Z92的原因里面有921 那解决方案有2种,但是要根据具体业务要求来 1、审视一下是否移动原因用错了 ?换一个移动原因 2、确实是这个移动类型 要用到这个移动原因 ,那就在上图 移…

Python编码系列—Python观察者模式:实现事件驱动架构的利器

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…

【数字ic自整资料】SV约束constraint

参考链接: SV--随机约束(一)_sv constraint-CSDN博客 SV--随机约束(二)_sv constraint f循环-CSDN博客 [SV]Constraint 遇到的问题_父类和子类 constraint-CSDN博客 目录 1、随机化的概念理解 2、约束(constrain…

基于报位时间判断船舶设备是否在线,基于心跳时间判断基站网络是否在线

文章目录 引言I 在线船舶查询在线或者离线船舶显示在线状态统计在线船舶II 树状显示船舶设备数据结构统计船舶设备在线数和总数III 基站网络是否在线IV 知识扩展统计某个key的数据,例如统计船舶分类下的在线船舶MyBatis引言 本文采用的数据库是SQL Server,开发语言为Java。 …

无线协议wlan在华为模拟器中的实现

无线技术 wifi6:标准为802.11; wifi发展趋势: vlan基本概念: wlan组网架构: 1)fat胖AP;能够独立工作,可以单独配置;小型网络使用,功能少; 2)fit瘦APAC:适用大型网络…

《深度学习》—— PyTorch的介绍及PyTorch的CPU版本安装

文章目录 一、PyTorch的简单介绍二、pytorch的CPU版本安装三、 torch、torchvision、torchaudio 三个库的介绍 一、PyTorch的简单介绍 PyTorch是一个由Facebook AI实验室开发的深度学习框架,它基于Python,并提供了高效的GPU加速和灵活的模型定义能力。1…

基于vue框架的传统服饰剪裁交流平台5m953(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能:用户,服装分类,服装资讯 开题报告内容 基于Vue框架的传统服饰剪裁交流平台开题报告 一、研究背景与意义 随着全球化进程的加速,文化多样性的保护与传承日益受到重视。传统服饰作为各民族历史文化的瑰宝,不仅承载…

阅读记录:Gradient Episodic Memory for Continual Learning

1. Contribution 提出了一组指标来评估模型在连续数据上的学习情况。这些指标不仅通过测试准确性来表征模型,还通过其跨任务迁移知识的能力来表征模型。针对持续学习任务,提出了GEM模型(Gradient Episodic Memory),它…

C++中stack类和queue类

感谢大佬的光临各位,希望和大家一起进步,望得到你的三连,互三支持,一起进步 数据结构习题_LaNzikinh篮子的博客-CSDN博客 初阶数据结构_LaNzikinh篮子的博客-CSDN博客 收入专栏:C_LaNzikinh篮子的博客-CSDN博客 其他专…

基于MT79815G CPE 板子上挂usb3.0的5G 模块,WIFI能跑多少速度呢

关于MT79815G CPE 板子上挂usb3.0的5G 模块,WIFI能跑多少速度的问题,我们以启明智显 ZX7981P智能无线接入型路由器(CPE)挂广合通5G模组为例说明: 一般来说,用 ZX7981P,通过软加速,U…

Java:列表操作

目录 1、判断列表是否为空或者为NULL2、列表包含3、列表排序4、列表截取5、列表合并6、列表求极值7、列表转字符串8、列表去重的四种方式9、列表转数组 1、判断列表是否为空或者为NULL Optional.ofNullable(list).orElse(Collections.emptyList()).isEmpty() // true为空或NU…

【JAVA-数据结构】时间空间复杂度计算案例

接着上一篇文章&#xff0c;对应举一些例子。 1.时间复杂度 【实例1】 // 计算func2的时间复杂度&#xff1f; void func2(int N) {int count 0;for (int k 0; k < 2 * N ; k) {count;} int M 10;while ((M--) > 0) {count;} System.out.println(count); } 基本操作…

在云渲染中3D工程文件安全性怎么样?

在云渲染中&#xff0c;3D工程文件的安全性是用户最关心的问题之一。随着企业对数据保护意识的增强&#xff0c;云渲染平台采取了严格的安全措施和加密技术&#xff0c;以确保用户数据的安全性和隐私性。 云渲染平台为了保障用户数据的安全&#xff0c;采取了多层次的安全措施。…