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

装饰器设计模式

    • 一. 介绍
    • 二. 代码示例
      • 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{@Overridepublic 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;}@Overridepublic 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);}@Overridepublic 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);}@Overridepublic 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.rhkb.cn/news/433715.html

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

相关文章

蓝桥杯--STM32G431RBT6(TIM定时器的输出频率和占空比,含详细原理介绍和使用方法)

目录 一、前言 二、代码 实现功能:​编辑 按如图配置 定义变量 编写执行代码 显示在LCD上 加入按键效果 三、效果展示 四、代码开源 一、前言 ARR 即自动重装载值(Auto Reload Register)。相当于一个水杯,水杯容量&am…

SpringCloud-Netflix第一代微服务快速入门

1.springCloud常用组件 Netflix Eureka 当我们的微服务过多的时候,管理服务的通信地址是一个非常麻烦的事情,Eureka就是用来管理微服务的通信地址清单的,有了Eureka之后我们通过服务的名字就能实现服务的调用。 Netflix Ribbon\Feign : 客…

性能测试常见故障和解决思路详解

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、性能问题分析流程 1、查看服务器的CPU、内存 、负载等情况,包括应用服务器和数据库服务器 2、查看数据库健康状态,数据库死锁、连…

【Java】单元测试【主线学习笔记】

文章目录 前言测试分类JUnit单元测试介绍编写单元测试方法的条件IDEA中简易使用JUnit 前言 Java是一门功能强大且广泛应用的编程语言,具有跨平台性和高效的执行速度,广受开发者喜爱。在接下来的学习过程中,我将记录学习过程中的基础语法、框架…

我们是向量数据库的领军企业,我们只招TOP人才

我们是全球领先的向量数据库企业,业务正在快速发展,现开放大量岗位: 前端、产品经理、数据库开发工程师、C、数据库运维、数据库测试…… 我们招聘的唯一目标,寻找 TOP人才! 如果你已经有丰富的经验,那么加…

【友元补充】【动态链接补充】

友元 友元的目的是让一个函数或者类,访问另一个类中的私有成员。 有缘的关键字friend是一个修饰符。 友元分为友元类和友元函数 1.全局函数作友元 2.类作友元 3.类的一个成员函数作友元 好处:可以通过友元在类外访问类内的私有和受保护类型的成员 坏处…

CC面试准备

半导体基础 半导体是介于导体和绝缘体之间的一种介质,在不同条件下表现出不同的导电性或者不导电特性, 电子半导体器件材料大部分为硅,锗等元素 本征半导体:完全不含杂质的纯净半导体,因为不含杂质,其中…

使用API有效率地管理Dynadot域名,设置域名服务器(NS)

前言 Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮箱&…

OCR识别系统 YOLOv8 +Paddle 方案落地

YOLOv8 PaddleOCR 技术方案落地 Yolov8相关文档Step 1 证件模型的训练Step 2 Yolov8进行图片推理Step 3 PaddleOCR进行识别Step 4 整合Yolov8 PaddleOCR 进行OCR Yolov8相关文档 《yolov8 官方网站》 《Yolov8 保姆级别安装》 Ultralytics YOLOv8 是一款尖端的、最先进的 (S…

【项目经验分享】深度学习自然语言处理技术毕业设计项目案例定制

以下毕业设计是与深度学习自然语言处理(NLP)相关的毕业设计项目案例,涵盖文本分类、生成式模型、语义理解、机器翻译、对话系统、情感分析等多个领域: 实现案例截图: 基于深度学习的文本分类系统基于BERT的情感分析系…

《AI大模型工程师》报考都学习哪些内容呢?

近年来,随着深度学习技术的迅猛发展,AI大模型已经成为人工智能领域的重要研究方向和热点话题。AI大模型,指的是拥有巨大参数规模和强大学习能力的神经网络模型,如BERT、GPT等,这些模型在自然语言处理、计算机视觉等领域…

Vue项目快速整合WangEditor富文本编辑器

Vue项目快速整合WangEditor富文本编辑器 一、安装依赖 npm i wangeditor --save //富文本编辑器 npm install highlight.js -S //代码高亮 npm install dompurify vue-dompurify-html // 防xss 库二、app.vue代码案例 已对接图片、视频接口 ,具体看如下代码…

使用canvas截取web camera指定区域,并生成图片

目标&#xff0c;截取红色色块背后的视频区域。 代码结构如下&#xff1a; <div id"p1"><video id"v1" autoplay playsinline></video><div id"mrz"></div><canvas id"captureCanvas"></can…

小程序开发设计-小程序的宿主环境:宿主环境简介⑥

上一篇文章导航&#xff1a; 小程序开发设计-小程序代码的构成&#xff1a;小程序页面的组成部分详解⑤-CSDN博客https://blog.csdn.net/qq_60872637/article/details/142306902?spm1001.2014.3001.5501 注&#xff1a;不同版本选项有所不同&#xff0c;并无大碍。 目录 上…

【C++】模板、宏、命名空间、

十五、C中的模板templates 本部分讨论C中的模板templates 在别的语言中&#xff0c;比如java、c、c#等托管语言中&#xff0c;模板类似泛型的概念&#xff0c;但模板比泛型要强大得多。模板有点像宏&#xff0c;而泛型却非常受限于类型系统以及其他很多因素。同时模板也是一个…

腾讯云SDK基本概念

本文旨在介绍您在使用音视频终端 SDK&#xff08;腾讯云视立方&#xff09;产品过程中可能会涉及到的基本概念。 音视频终端 SDK&#xff08;腾讯云视立方&#xff09; 应用 音视频终端 SDK&#xff08;腾讯云视立方&#xff09;通过应用的形式来管理您的项目&#xff08;Ap…

net core mvc 数据绑定 《1》

其它的绑定 跟net mvc 一样 》》MVC core 、framework 一样 1 模型绑定数组类型 2 模型绑定集合类型 3 模型绑定复杂的集合类型 4 模型绑定源 》》》》 模型绑定 使用输入数据的原生请求集合是可以工作的【request[],Querystring,request.from[]】&#xff0c; 但是从可读…

【一文读懂】C#如何实现通用的排序功能

目录 通用排序功能 1.升序 2.降序 测试 1.测试代码 2.测试结果 本篇文章来分享一下C#如何实现通用的排序功能。在项目中经常会使用到排序的方法&#xff0c;那如何使排序方法更加通用呢&#xff1f;可以通过泛型&#xff0c;接口&#xff0c;委托来实现。 通用排序功能…

学校周赛(1)

A - Short Sort 题目&#xff1a; 思路&#xff1a; 本条题目只允许改一处地方&#xff0c;只有三个字母&#xff0c;我们可以直接枚举所有移动过的结果&#xff0c;同时使用哈希去记录其值&#xff0c;对于每一个输入我们都寻找是否有这个值记录&#xff0c;有则输出YES否则…

数据结构与算法——Java实现 19.队列

目录 一、概述 二、链表实现队列 接口定义 接口实现类 测试类 三、环形数组实现队列 优点 下标计算 判满和判空 判满 判空 辅助变量size判空和判满 方法1 接口定义 接口实现类 测试类 方式2 接口定义 接口实现类 测试类 方法3 接口定义 接口实现类 测试类 生活鲜少给人留下退…