Java特性之设计模式【装饰器模式】
一、装饰器模式
概述
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装
装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为
主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀
何时使用:在不想增加很多子类的情况下扩展类
优缺点
优点:
- 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能
缺点:
- 多层装饰比较复杂
1. 各个角色介绍
1.1 抽象组件(Component)
- 定义了组合中所有对象的通用接口,可以是抽象类或接口。它声明了用于访问和管理子组件的方法,包括添加、删除、获取子组件等
1.2 具体组件(Concrete Component)
- 是被装饰的原始对象,它定义了需要添加新功能的对象
1.3 抽象装饰器(Decorator)
- 继承自抽象组件,它包含了一个抽象组件对象,并定义了与抽象组件相同的接口,同时可以通过组合方式持有其他装饰器对象
1.4 具体装饰器(Concrete Decorator)
- 实现了抽象装饰器的接口,负责向抽象组件添加新的功能。具体装饰器通常会在调用原始对象的方法之前或之后执行自己的操作
2. UML图
将创建一个 Shape 接口和实现了 Shape 接口的实体类。然后创建一个实现了 Shape 接口的抽象装饰类 ShapeDecorator,并把 Shape 对象作为它的实例变量。RedShapeDecorator 是实现了 ShapeDecorator 的实体类

3. 具体例子和代码
角色分配
-
Shape:形状接口
- Rectangle:实现形状接口的长方形类
- Circle:实现形状接口的圆形类
-
ShapeDecorator:形状装饰器抽象类
- RedShapeDecorator:红色形状装饰器(继承ShapeDecorator)
3.1 抽象组件及其实现类
- Shape
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 形状接口* @since 2024/3/15 16:23*/
public interface Shape {/*** 形状绘制动作*/void draw();}
- Rectangle
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 长方形* @since 2024/3/15 16:26*/
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Shape: Rectangle");}}
- Circle
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 圆形* @since 2024/3/15 16:28*/
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Shape: Circle");}}
3.2 抽象装饰器及其具体装饰器
- ShapeDecorator
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 形状装饰器* @since 2024/3/15 16:30*/
public abstract class ShapeDecorator implements Shape {protected Shape decoratedShape;public ShapeDecorator(Shape decoratedShape) {this.decoratedShape = decoratedShape;}public void draw() {decoratedShape.draw();}}
- RedShapeDecorator
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 红色形状装饰器* @since 2024/3/15 16:32*/
public class RedShapeDecorator extends ShapeDecorator {public RedShapeDecorator(Shape decoratedShape) {super(decoratedShape);}@Overridepublic void draw() {decoratedShape.draw();setRedBorder(decoratedShape);}private void setRedBorder(Shape decoratedShape) {System.out.println("Border Color: Red");}}
3.3 测试主函数
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 装饰器模式* @since 2024/3/15 16:39*/
public class Main {public static void main(String[] args) {Shape circle = new Circle();// ShapeDecorator redCircle = new RedShapeDecorator(new Circle());// ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());Shape redCircle = new RedShapeDecorator(new Circle());Shape redRectangle = new RedShapeDecorator(new Rectangle());System.out.println("Circle with normal border");circle.draw();System.out.println("\nCircle of red border");redCircle.draw();System.out.println("\nRectangle of red border");redRectangle.draw();}}
- 测试结果

4. 使用场景
- 动态增强功能:使用装饰器模式可在运行时为对象灵活地增加额外功能。通过组合各种装饰器,能够实现不同功能的组合,而无需改变原始对象的代码
- 避免继承的功能扩展:当使用继承来增强对象功能时会导致类的层次结构过于复杂时,考虑采用装饰器模式。通过组合而非继承来实现功能扩展,避免了深层次和复杂的类继承结构
- 维护对象的封装性:若需为对象添加功能,同时又不愿修改原始对象的代码或破坏其封装性,可采用装饰器模式。该模式不改变原对象结构,只是在其上方增添功能
- 弹性组合多项功能:若需为对象添加多项功能,且这些功能可弹性组合,则可采用装饰器模式。透过组合各种装饰器,能够实现各种功能的组合,而无需创建大量子类
- 贯彻单一职责原则:在需要将功能添加与原始对象实现分离,以符合单一职责原则时,可采用装饰器模式。每个装饰器类专注于一个特定功能,这有助于使类的职责更加明确

相关文章:
Java特性之设计模式【装饰器模式】
一、装饰器模式 概述 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装 装饰器模式通过将对象包装在装饰器类中,以…...
Leetcode算法题笔记(2)
目录 图论51. 岛屿数量解法一 52. 腐烂的橘子解法一 53. 课程表解法一 54. 实现 Trie (前缀树)解法一 回溯55. 全排列解法一 56. 子集解法一解法二 57. 电话号码的字母组合解法一 58. 组合总和解法一解法二 59. 括号生成解法一解法二 60. 单词搜索解法一 61. 分割回文串解法一 …...
二手车交易网站|基于JSP技术+ Mysql+Java+ B/S结构的二手车交易网站设计与实现(可运行源码+数据库+设计文档)
推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java,ssm,springboot的平台设计与实现项目系统开发资源(可…...
lora-scripts 训练IP形象
CodeWithGPU | 能复现才是好算法CodeWithGPU | GitHub AI算法复现社区,能复现才是好算法https://www.codewithgpu.com/i/Akegarasu/lora-scripts/lora-trainstable-diffusion打造自己的lora模型(使用lora-scripts)-CSDN博客文章浏览阅读1.1k次…...
Acwing 503. 借教室
Problem: 503. 借教室 文章目录 思路解题方法复杂度Code 思路 这是一个二分查找问题。我们需要找到最大的借教室数量,使得每个教室的借用时间不超过其可用时间。我们可以通过二分查找来找到这个最大的借教室数量。 解题方法 我们首先对所有的借教室请求按照结束时间…...
吴恩达深度学习笔记:浅层神经网络(Shallow neural networks)3.1-3.5
目录 第一门课:神经网络和深度学习 (Neural Networks and Deep Learning)第三周:浅层神经网络(Shallow neural networks)3.1 神经网络概述(Neural Network Overview)3.2 神经网络的表示(Neural Network Representation…...
Linux设备驱动开发 - 三色LED呼吸灯分析
By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 展锐UIS7885呼吸灯介绍呼吸灯调试方法亮蓝灯亮红灯亮绿灯展锐UIS7885呼吸灯DTS配置ump9620 PMIC驱动ump9620中的LED呼吸灯驱动LED的tr…...
开发者的瑞士军刀:DevToys
DevToys: 一站式开发者工具箱,打造高效创意编程体验,让代码生活更加得心应手!—— 精选真开源,释放新价值。 概览 不知道大家是否在windows系统中使用过PowerToys?这是微软研发的一项免费实用的系统工具套…...
【vue3.0】实现导出的PDF文件内容是红头文件格式
效果图: 编写文件里面的主要内容 <main><div id"report-box"><p>线索描述</p><p class"label"><span>线索发现时间:</span> <span>{{ detailInfoVal?.problem.createdDate }}</span></p><…...
【CSP试题回顾】202012-2-期末预测之最佳阈值(优化)
CSP-202012-2-期末预测之最佳阈值 关键点 1.map的遍历方式 map<int, int>occ0Num, occ1Num; for (auto it thetaSet.begin(); it ! thetaSet.end(); it) {num num occ0Num[*it] - occ1Num[*it];auto nextIt next(it); // 获取下一个迭代器if (num > maxNum &a…...
docker学习笔记 三-----docker安装部署
我使用的部署环境是centos 7.9 1、安装依赖工具 yum install -y yum-utils device-mapper-persistent-data lvm2 安装完成如下图 2、添加docker的软件信息源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo url地址为如…...
FastAPI+React全栈开发02 什么是FARM技术栈
Chapter01 Web Development and the FARM Stack 02 What is the FARM stack and how does it fit together? FastAPIReact全栈开发02 什么是FARM技术栈 It is important to understand that stacks aren’t really special, they are just sets of technologies that cover…...
C#程序结构详解
目录 背景: 一、C#程序的基本组成部分 二、C# Hello World示例 三、程序结构解析 四、编译与执行C#程序 五、总结 背景: 在学习C#编程语言的过程中,了解程序的基本结构是非常重要的。C#程序由多个组成部分构成,每个部分都有其特定的功能和作用。下面…...
linux 清理空间
1. 根目录下执行命令,查看每个目录下文件大小总和 rootvm10-88-88-3 /]# du -h --max-depth1 79M ./tmp 123M ./etc 4.0K ./media 4.0K ./srv 104M ./boot 5.3G ./var 0 ./sys 8.6M ./dev 196G ./usr 4.0K ./mnt 285M ./opt…...
C语言:给结构体取别名的4种方法
0 前言 在进行嵌入式开发的过程中,我们经常会见到typedef这个关键字,这个关键字的作用是给现有的类型取别名,在实际使用过程中往往是将一个复杂的类型名取一个简单的名字,便于我们的使用。就像我们给很熟的人取外号一样ÿ…...
今天聊聊Docker
在数字化时代,软件应用的开发和部署变得越来越复杂。环境配置、依赖管理、版本控制等问题给开发者带来了不小的挑战。而Docker作为一种容器化技术,正以其独特的优势成为解决这些问题的利器。本文将介绍Docker的基本概念、优势以及应用场景,帮…...
【C语言】结构体
个人主页点这里~ 结构体 一、结构体类型的声明1、结构的声明2、结构体变量的创建和初始化3、声明时的特殊情况4、自引用 二、结构体内存对齐1、对齐规则2、存在内存对齐的原因3、修改默认对齐数 三、结构体传参四、结构体实现位段 一、结构体类型的声明 我们在指针终篇中提到过…...
Git基础(24):分支回退
文章目录 前言放弃已修改的内容分支回退到指定commit 前言 将分支回退到之前的某个版本 开发中,可能开发某个功能不需要了,或者想要回退到之前历史的某个commit, 放弃后来修改的内容。 放弃已修改的内容 如果未提交,直接使用 …...
复试专业前沿问题问答合集1
复试专业前沿问题问答合集1 人工智能基础知识问答 Q1: 什么是人工智能(AI)? A1: 人工智能(AI)是计算机科学的一个分支,它涉及创建能够执行通常需要人类智能的任务的机器和软件。这些任务包括学习(获取信息并根据信息对其进行规则化以达到结论)、推理(使用规则达到近…...
C++标准库中提供的用于处理正则表达式的类std::regex
std 是 C 标准库的命名空间,包含了大量标准的 C 类、函数和对象。这些类和函数提供了广泛的功能,包括输入输出、容器、算法、字符串处理等。 通常,为了使用标准库中的对象和函数,需在代码中包含相应的头文件,比如 #in…...
混合量子-经典机器学习在HPC环境下的性能调优与实战
1. 项目概述与核心价值在人工智能和计算科学的前沿,我们正站在一个关键的十字路口。一方面,以卷积神经网络为代表的经典机器学习模型,在处理图像识别、自然语言理解等任务上取得了巨大成功,但其对计算资源的需求正以惊人的速度膨胀…...
智能体通信的序列化标准探索:JSON、ProtoBuf与自定义格式的效率之争
智能体通信的「快递员之战」:JSON、ProtoBuf与自定义格式的效率深度探索 关键词 智能体通信、序列化/反序列化、JSON、Protocol Buffers、自定义二进制格式、传输效率、编码效率、跨语言兼容 摘要 在人工智能多智能体系统(Multi-Agent System, MAS)、大语言模型(LLM)驱…...
5个高效模组管理技巧:打造完美的XCOM 2游戏体验
5个高效模组管理技巧:打造完美的XCOM 2游戏体验 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom…...
Goby新版插件深度解析:PbootCMS 3.1.2远程代码执行漏洞检测与利用
1. 这个Goby插件更新不是“打补丁”,而是给红队装了一把新钥匙你有没有遇到过这样的情况:扫出一台PbootCMS站点,版本号赫然写着3.1.2,Goby却只标了个“中危”甚至不报——结果手工验证时,一个POST请求就弹出了shell&am…...
编写团队创意迭代记录程序,记录创意修改优化过程,形成完整创新迭代档案。
一、实际应用场景描述在真实团队创新过程中,常见如下场景:- 头脑风暴产生大量创意- 评审后不断修改、合并、推翻- 半年后再回顾,“谁提的?为什么改?最初长什么样?”已经模糊- 新成员加入,无法理…...
App爬虫实战:突破SSL Pinning、动态签名与设备指纹的五层反爬
1. 这不是写个 requests 就能跑通的“爬虫”,而是一场持续数月的攻防拉锯战“App 父亲”这个词在移动互联网圈里没人真叫,但所有做过 App 数据采集的人心里都清楚——你面对的从来不是一串 API 接口,而是一个被精心加固、层层设防、会主动识别…...
保姆级教程:在Ubuntu 20.04上搞定浙大lidar_IMU_calib(从编译到避坑)
保姆级教程:在Ubuntu 20.04上搞定浙大lidar_IMU_calib(从编译到避坑)当激光雷达(LiDAR)和惯性测量单元(IMU)需要协同工作时,标定这两个传感器之间的外参是必不可少的步骤。浙大开源项…...
ChatGPT翻译质量真相:20年本地化专家实测12类文本(技术文档/法律合同/文学隐喻),准确率暴跌的3个致命盲区!
更多请点击: https://intelliparadigm.com 第一章:ChatGPT翻译质量怎么样 ChatGPT 在多语种翻译任务中展现出较强的上下文理解与语义连贯能力,尤其在非技术类通用文本(如日常对话、新闻摘要、文学性段落)上࿰…...
FlashMLA:把 KV Cache 压缩到原来的八分之一
标准 MHA 的 KV Cache 是推理显存的第一大户。LLaMA-7B,32 层,每层 32 头,HeadDim128,SeqLen128K——KV Cache 吃 40GB。MLA(Multi-head Latent Attention)用低秩分解把 KV 映射到一个远小于 HeadDim 的潜在…...
Node.js 服务端应用无缝接入 TaoToken 多模型 API 的配置详解
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Node.js 服务端应用无缝接入 TaoToken 多模型 API 的配置详解 对于 Node.js 后端开发者而言,为应用快速集成大模型能力…...
