Java—装饰器模式
介绍
装饰器模式
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地将行为添加到现有的对象中,而无需修改其代码。装饰器模式提供了比继承更灵活的功能扩展方式。
主要角色
- Component:定义一个对象接口,可以给这些对象动态地添加职责。
- ConcreteComponent:具体实现Component接口的类,即被装饰器装饰的原始对象。
- Decorator:装饰器基类,持有一个Component对象的引用,并且与Component接口保持一致。
- ConcreteDecorator:具体的装饰器类,实现具体要向Component添加的功能。
Java代码实现示例
我们将通过一个简单的例子来演示装饰器模式。假设我们有一个基本的消息发送系统,能够发送简单的文本消息。现在我们希望能够在发送消息之前对消息进行加密,并在发送之后记录日志。
定义组件接口和具体组件
// Component
interface Message {String send();
}// ConcreteComponent 被装饰者
class TextMessage implements Message {private String content;public TextMessage(String content) {this.content = content;}@Overridepublic String send() {return "Sending message: " + content;}
}
定义装饰器基类和具体装饰器
// Decorator 装饰者 (增强)
abstract class MessageDecorator implements Message {protected Message wrapped;public MessageDecorator(Message wrapped) {this.wrapped = wrapped;}@Overridepublic String send() {return wrapped.send();}
}// ConcreteDecoratorA
class EncryptedMessageDecorator extends MessageDecorator {public EncryptedMessageDecorator(Message wrapped) {super(wrapped);}@Overridepublic String send() {String originalMessage = wrapped.send();String encryptedMessage = encrypt(originalMessage);return "Encrypted(" + encryptedMessage + ")";}private String encrypt(String message) {// 简单的模拟加密逻辑StringBuilder encrypted = new StringBuilder(message);return encrypted.reverse().toString();}
}// ConcreteDecoratorB
class LoggedMessageDecorator extends MessageDecorator {public LoggedMessageDecorator(Message wrapped) {super(wrapped);}@Overridepublic String send() {String result = wrapped.send();log(result);return result;}private void log(String message) {System.out.println("Logging: " + message);}
}
使用装饰器模式
public class Main {public static void main(String[] args) {Message message = new TextMessage("Hello, World!");// 使用加密装饰器Message encryptedMessage = new EncryptedMessageDecorator(message);System.out.println(encryptedMessage.send()); // 输出加密后的消息// 使用日志装饰器Message loggedMessage = new LoggedMessageDecorator(message);System.out.println(loggedMessage.send()); // 日志消息并输出// 组合装饰器Message encryptedLoggedMessage = new LoggedMessageDecorator(new EncryptedMessageDecorator(message));System.out.println(encryptedLoggedMessage.send()); // 输出加密并记录日志的消息}
}
运行结果

解释
- Message接口:定义了发送消息的方法
send。 - TextMessage类:实现了Message接口,表示一个简单的文本消息。
- MessageDecorator抽象类:也是Message接口的实现,但它持有一个Message对象,并在其方法调用时委托给该对象。
- EncryptedMessageDecorator类:扩展MessageDecorator,通过重写
send方法添加加密功能。 - LoggedMessageDecorator类:扩展MessageDecorator,通过重写
send方法添加日志记录功能。
通过这种方式,我们可以在不修改原始类的情况下,为对象动态添加新功能。这提供了一种比继承更灵活、可扩展性更强的方式来增强对象的行为。
类图
装饰器模式(Decorator Pattern)是一种结构型设计模式,允许你通过将对象放入包装对象中来动态地添加行为,相比继承更加灵活。以下是装饰器模式的类图示例:
+----------------------------------+
| Component |
+----------------------------------+
| operation(): void |
+----------------------------------+^||
+-----------------------------+
| ConcreteComponent |
+-----------------------------+
| operation(): void |
+-----------------------------+△|
+-----------------------------+
| Decorator |
+-----------------------------+
| component: Component |
| operation(): void |
+-----------------------------+||
+-----------------------------+
| ConcreteDecoratorA |
+-----------------------------+
| operation(): void |
| addedBehavior(): void |
+-----------------------------+△|
+-----------------------------+
| ConcreteDecoratorB |
+-----------------------------+
| operation(): void |
| addedBehavior(): void |
+-----------------------------+
说明:
-
Component(抽象构件):
- 定义一个对象接口,可以给这些对象动态地添加职责。
operation()是抽象操作,可以是接口或者抽象类。
-
ConcreteComponent(具体构件):
- 定义一个具体的对象,也可以给这个对象添加一些职责。
-
Decorator(装饰器抽象类):
- 持有一个 Component 对象的引用,并定义一个与 Component 接口一致的接口。
- 可以用来装饰 Component 对象,增加其行为。
-
ConcreteDecoratorA、ConcreteDecoratorB(具体装饰器):
- 负责给具体构件对象添加额外的职责。
类图说明:
- Component 是抽象构件角色,定义了对象接口。
- ConcreteComponent 是具体构件角色,实现了 Component 接口的具体对象。
- Decorator 是装饰器抽象类,持有一个 Component 对象的引用,并定义了与 Component 接口一致的接口。
- ConcreteDecoratorA、ConcreteDecoratorB 是具体装饰器类,实现了 Decorator 定义的接口,负责给 Component 对象添加额外的职责。
装饰器模式的核心是通过组合而非继承来扩展对象的功能,使得动态添加功能更加灵活。
相关文章:
Java—装饰器模式
介绍 装饰器模式 装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地将行为添加到现有的对象中,而无需修改其代码。装饰器模式提供了比继承更灵活的功能扩展方式。 主要角色 Component:定义一个对…...
服务器远程桌面经常连接不上,造成远程桌面连接不上的原因都有哪些
服务器远程桌面连接不稳定或经常连接不上是一个较为常见的技术问题,其可能的原因涉及多个层面,包括网络设置、服务器配置、系统安全等方面。下面将详细探讨一些可能造成远程桌面连接问题的主要原因: 首先,网络连接不稳定是导致远…...
C#|Maui|BootstrapBlazor|Bootstrap Blazor 组件库改模板 | Bootstrap Blazor 组件库改布局,该怎么改?
先copy一个项目下来:Bootstrap Blazor 组件库 一套基于 Bootstrap 和 Blazor 的企业级组件库 发现不是很满足我的需求,我要把右下角的admin移动到左边去,该怎么移动? 先改代码 点进去到Layout.razor 文档,改成如下&am…...
【Linux】I/O多路复用
文章目录 I/O多路复用select()select()缺点 poll()poll()缺点 epoll()LT(水平触发模式)ET(边缘触发模式)具体函数 I/O多路复用 多进程和多线程实现并发会消耗大量的资源,主进程/线程用于监听和接受连接,再创建多个子进程/子线程来完成与连接的各个客户端…...
ubuntu20.0.4下安装PyTorch
参考文档 https://datawhalechina.github.io/thorough-pytorch/%E7%AC%AC%E4%B8%80%E7%AB%A0/1.2%20PyTorch%E7%9A%84%E5%AE%89%E8%A3%85.html 1:安装Anaconda 登录Anaconda | Individual Edition,https://www.anaconda.com/download/success ÿ…...
Android屏幕旋转流程(1)
(1)Gsensor的注册和监听 App -->I2C过程:App通过SensorManager.getSystemServer调用到SystemSensorManager,SystemSensorManager通过jni调用到SensorManager.cpp,后通过binder调用到SensorService。SensorService通…...
JS常见的运算符有哪些?
在JavaScript中,常见的运算符可以分为以下几类: 算术运算符: :加法-:减法*:乘法/:除法%:取余(模运算):递增--:递减**:幂运…...
【scikit-learn入门指南】:机器学习从零开始
1. 简介 scikit-learn是一款用于数据挖掘和数据分析的简单高效的工具,基于NumPy、SciPy和Matplotlib构建。它能够进行各种机器学习任务,如分类、回归和聚类。 2. 安装scikit-learn 在开始使用scikit-learn之前,需要确保已经安装了scikit-le…...
MEMS:Lecture 17 Noise MDS
讲义 Minimum Detectable Signal (MDS) Minimum Detectable Signal(最小可检测信号)是指当信号-噪声比(Signal-to-Noise Ratio, SNR)等于1时的输入信号水平。简单来说,MDS 是一个系统能够分辨出信号存在的最低输入信号…...
Windows运维:找到指定端口的服务
运维过windows的或多或少都遇到过需要找到一个端口对应的服务,或者是因为端口占用,或者是想看下对应的服务是哪个,那么如何操作呢?看看本文吧。 1、按照端口找到进程ID 例如想找8000端口的进程ID netstat -ano | findstr :8000 2…...
Linux文件系统讲解!
一、Linux文件系统历史 1、在早期的时候Linux各种不同发行版拥有自己各自自定义的文件系统层级结构。 2、当我用Red hat转向玩Debian时,我进入/etc我都是懵的。 3、后来Linux社区做了一个标准、FHS(文件系统标准层次结构)。来帮助Linux系统的…...
mysql集群,两主两从,使用mysql-proxy实现读写分离
主从复制 一、IP规划 服务器IP备注master1192.168.100.131master2的从master2192.168.100.132master1的从slave1192.168.100.134slave1的从slave2192.168.100.135slave2的从mysql-proxy192.168.100.137 二、具体配置 1.master1 配置ip:192.168.100.131 …...
Linux文本处理三剑客+正则表达式
Linux文本处理常用的3个命令,脚本或者文本处理任务中会用到。这里做个整理。 三者的功能都是处理文本,但侧重点各不相同,grep更适合单纯的查找或匹配文本,sed更适合编辑匹配到的文本,awk更适合格式化文本,对…...
Linux启动KKfileview文件在线浏览时报错:启动office组件失败,请检查office组件是否可用
目录 1、导论 2、报错信息 3、问题分析 4、解决方法 4.1、下载 4.2、安装步骤 1、导论 今天进行项目部署时,遇到了一个问题。在启动kkfileview时,出现了报错异常: 2024-06-09 06:36:44.765 ERROR 1 --- [ main] cn.keking.service.Of…...
React <> </>的用法
React <> </>的用法 介绍为什么使用 <>?例子解释 关于顶级元素总结 介绍 在 React 中,使用 <> 表示一个空标签或片段(Fragment),这是一个简洁的方式来包裹一…...
is not null 、StringUtils.isNotEmpty和StringUtils.isNotBlank之间的区别?
这三者主要是针对对象是否为空、是否为空串和是否为空白字符串有不同的功能。 is not null 只是说明该对象不为空,没有考虑是否为空串和空白字符串。 StringUtils.isNotEmpty检查字符串是否不为 null且长度大于零,不考虑字符串中的空白字符。 StringU…...
Git使用-gitlab上面的项目如何整到本地的idea中
场景 一般我们在开发项目或者接手某个项目时,基本都要接触Git,比如上传项目代码,下载同事给你的交接代码等等。 这是一个基本功,小小整理一下日常操作中的使用。 第一步:在 GitLab 上找到你要克隆的项目,复…...
活体检验API在Java、Python、PHP中的使用教程
活体检验API是一种基于生物特征的身份验证技术,通过分析和识别用户的生物信息来确认其身份。这种技术广泛应用于各种领域,如金融、安全、社交媒体等,以提高身份验证的安全性和准确性。以下是描述”活体检验API”背景的一些关键点:…...
智能计算系统-概述
1、人工智能技术分层 2、人工智能方向人才培养 3、课程体系的建议 4、智能系统课程对学生的价值 5、智能计算系统对老师的价值 6、什么是智能计算系统 7、智能计算系统的形态 8、智能计算系统具有重大价值 9、智能计算系统的三大困难 10、开创深度学习处理器方向 11、寒武纪的国…...
SM5101 SOP-8 充电+触摸+发执丝控制多合一IC触摸打火机专用IC
SM5101 SOP-8 2.7V 涓流充电 具电池过充过放 触摸控制 发热丝电流控制多功能为一体专用芯片 昱灿-海川 SM5101 SOP-8 充电触摸发执丝控制多合一IC触摸打火机方案 !!! 简介: SM5101是一款针对电子点烟器的专用芯片,具…...
【基于Tube的非线性系统模型预测控制MPC】基于鲁棒控制不变集的管式模型预测控制方案及其在利普希茨非线性系统中的应用附Matlab代码
✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…...
02.Linux常用文件操作命令
1.mkdir 目录名:创建目录 mkdir 目录名 mkdir -p a/b/c 创建多级目录 2.touch 创建空文件 touch 文件名 touch 文件名 文件名 创建多个文件 3.文件写入内容 echo写入 覆盖写入 echo 文件内容 >文件名 追加写入(日志必用) echo 文件内容 >…...
从外卖配送看算法实战:Python+NetworkX解决简化版VRP问题
外卖配送路径优化实战:用PythonNetworkX解决简化版VRP问题 中午12点,城市里的外卖订单如潮水般涌来。配送员小张的手机上瞬间出现了8个不同方向的订单,他盯着地图上分散的标记点皱起了眉头——怎样才能用最短的时间送完所有外卖?这…...
RSA宣布与Microsoft扩大合作,进一步巩固公司在无密码身份安全领域的领导地位
创新合作开启安全、基于人工智能的员工身份验证新时代 RSA今日在RSAC 2026大会上宣布,将扩大对全新Microsoft 365 E7:The Frontier Suite解决方案的支持。这一新增支持结合了额外的无密码功能,在企业拥抱人工智能驱动的生产力未来之际&#…...
Laravel Backup隔离模式详解:多服务器环境下的终极安全备份方案
Laravel Backup隔离模式详解:多服务器环境下的终极安全备份方案 【免费下载链接】laravel-backup A package to backup your Laravel app 项目地址: https://gitcode.com/gh_mirrors/la/laravel-backup Laravel Backup包为Laravel应用提供了强大可靠的备份解…...
vs code 实现source insight中的快捷键功能
1.自定义快捷键连续两组快捷键CtrlK CtrlS打开键盘快捷键定义界面修改向前向后的快捷键。ctrlu删除当前行复制当前行到下面2.增加bookmarks功能扩展部分装插件,定义快捷键ctrlm增加标签可以修改标签3.多行移动多行向上移动,向下移动Windows/Linux 用 Alt…...
Git 代码库中找回丢失文件的实用指南
1. 为什么Git能帮你找回丢失的代码? 作为开发者,你一定遇到过这样的场景:不小心执行了rm -rf删错了文件,或者手滑把整个功能模块给覆盖了。这时候千万别慌,Git就像个贴心的时光机,能帮你找回99%的丢失文件。…...
Stable Diffusion XL 1.0开源大模型教程:灵感画廊app.py核心逻辑解读
Stable Diffusion XL 1.0开源大模型教程:灵感画廊app.py核心逻辑解读 “见微知著,凝光成影。将梦境的碎片,凝结为永恒的视觉诗篇。” 如果你对AI绘画感兴趣,一定听说过Stable Diffusion XL 1.0这个强大的开源模型。但面对复杂的参…...
告别手动调参!模糊PID如何让直流电机在负载突变时稳如泰山?
模糊PID控制:让直流电机在负载突变时稳如泰山的实战指南 引言:工业自动化中的电机控制痛点 在自动化产线上,直流电机突然遭遇负载变化时,你是否也经历过这样的场景?——机械臂正在精准抓取工件,突然因为物料…...
ArcSWAT实战避坑指南 | 从数据库配置到模型运行,详解常见报错与高效解决方案
1. ArcSWAT入门避坑:从安装到首次运行的关键准备 第一次接触ArcSWAT的水文研究者,往往会在安装环节就踩坑。我见过太多人因为版本兼容性问题,导致后续模型根本无法启动。这里分享几个血泪教训: ArcGIS版本选择是首要关键。虽然官方…...
