Java—装饰器模式

介绍

装饰器模式

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地将行为添加到现有的对象中,而无需修改其代码。装饰器模式提供了比继承更灵活的功能扩展方式。

主要角色
  1. Component:定义一个对象接口,可以给这些对象动态地添加职责。
  2. ConcreteComponent:具体实现Component接口的类,即被装饰器装饰的原始对象。
  3. Decorator:装饰器基类,持有一个Component对象的引用,并且与Component接口保持一致。
  4. 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());  // 输出加密并记录日志的消息}
}

运行结果

解释

  1. Message接口:定义了发送消息的方法 send
  2. TextMessage类:实现了Message接口,表示一个简单的文本消息。
  3. MessageDecorator抽象类:也是Message接口的实现,但它持有一个Message对象,并在其方法调用时委托给该对象。
  4. EncryptedMessageDecorator类:扩展MessageDecorator,通过重写 send 方法添加加密功能。
  5. 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       |
+-----------------------------+

说明:

  1. Component(抽象构件)

    • 定义一个对象接口,可以给这些对象动态地添加职责。
    • operation() 是抽象操作,可以是接口或者抽象类。
  2. ConcreteComponent(具体构件)

    • 定义一个具体的对象,也可以给这个对象添加一些职责。
  3. Decorator(装饰器抽象类)

    • 持有一个 Component 对象的引用,并定义一个与 Component 接口一致的接口。
    • 可以用来装饰 Component 对象,增加其行为。
  4. ConcreteDecoratorA、ConcreteDecoratorB(具体装饰器)

    • 负责给具体构件对象添加额外的职责。

类图说明:

  • Component 是抽象构件角色,定义了对象接口。
  • ConcreteComponent 是具体构件角色,实现了 Component 接口的具体对象。
  • Decorator 是装饰器抽象类,持有一个 Component 对象的引用,并定义了与 Component 接口一致的接口。
  • ConcreteDecoratorA、ConcreteDecoratorB 是具体装饰器类,实现了 Decorator 定义的接口,负责给 Component 对象添加额外的职责。

装饰器模式的核心是通过组合而非继承来扩展对象的功能,使得动态添加功能更加灵活。

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

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

相关文章

变量不自动初始化

代码: /*《AVR专题精选》随书例程2.编程技巧项目:不对变量进行初始化文件:main.c说明:演示不对变量进行默认初始化的方法。在proteus仿真例程中,按下按键,就可以看到两个变量输出结果的变化。作者&#xf…

今日事、今日毕,任务管理系统

使用 C 实现的今日事,今日毕,任务管理系统。

解决上一篇误删问题的改进(增加线程标识校验)

本文将基于上一篇文章介绍如何通过改进 Redis 分布式锁的实现来解决误删问题。 分布式锁的改进实现 1. 误删问题的原因 在原始实现中,分布式锁通过 Redis 的 setIfAbsent 方法获取锁,并通过 delete 方法释放锁。然而,在某些情况下&#xf…

web前端defer:深度解析与实用指南

web前端defer:深度解析与实用指南 在web前端开发中,defer是一个关键的属性,它影响着脚本的加载和执行方式。然而,对于许多开发者来说,defer的真正含义和用法却常常带来困惑。本文将通过四个方面、五个方面、六个方面和…

Python的print,input与注释的使用

1.print的使用 2.input的使用 3.如何注释 1.print的使用 1.1建立俩个变量a,b,直接把变量放在print的括号里面就会打印其的值。 1.2print可以同时打印多个,打印ab的值与字符串‘11’。 1.3先用chr()函数去获取对应97…

剖析 Kafka 消息丢失的原因

文章目录 前言一、生产者导致的消息丢失的场景场景1:消息太大解决方案 :1、减少生产者发送消息体体积2、调整参数max.request.size 场景2:异步发送机制解决方案 :1、使用带回调函数的发送方法 场景3:网络问题和配置不当…

定义仅限关键字参数

定义仅限关键字参数 Python里的函数不光支持通过有序位置参数(positional argument)调用,还能指定参数名,通过关键字参数(keyword argument)的方式调用。 比如下面这个用户查询函数: def que…

0x0000007b应用程序错误解决

系统win7 一 问题 今天部署应用程序到win7系统上,双击应用程序弹出了0x0000007b的错误。 二 vcredist 2.1 简介 一般用Visual C开发的Windows应用程序需要这个运行时库的支持才能在没有安装Visual C的计算机上正常运行,也可以在开发软件时选择”在静…

Python爬虫实战案例之——MySql数据入库

Hello大家好,我是你们的南枫学长,咱们今天来学——爬虫之MySql数据入库。 话不多说,导入咱们的老朋友: Pymysql就是我们Python里面的mysql库,主要功能就是用来连接MySql数据库,那么下载还是一样的操作去进…

自动驾驶规划-RTT* 算法 【免费获取Matlab代码】

目录 1.算法原理3.结果展示4.参考文献5.代码获取 1.算法原理 RRT(Rapidly-Exploring Random Trees) 快速随机扩展树,是一种单一查询路径规划算法。RRT 将根节点作为搜索的起点,然后通过随机撒点采样增加叶子节点的方式,生成一个随机扩展树&a…

STM32开发过程中碰到的问题总结 - 3

文章目录 前言1. keil5升级到最新版本使用armV6编译工具链编译不通过2. 最新的keil用Jlink调试失败3. 移动了目录后跑不起来了4. 串口兼容了GNU 和arm只会,编译出来的成果物,串口输出不正常5.STM32下哪些IO口可以作为中断触发去使用6. 触发GPIO10的外部中…

如何优化 Bash 脚本的执行效率?

要优化 Bash 脚本的执行效率,可以考虑以下几个方面: 减少命令执行次数:Bash 脚本中的命令执行是比较耗时的,在可能的情况下,可以尽量减少命令的执行次数。例如,可以将多个命令合并成一个,使用管…

【Go语言】面向对象编程(二):通过组合实现类的继承和方法重写

通过组合实现类的继承和方法重写 要实现面向对象的编程,就必须实现面向对象编程的三大特性:封装、继承和多态。 1 封装 类的定义及其内部数据的定义可以看作是类的属性,基于类定义的函数方法则是类的成员方法。 2 继承 Go 语言中&#x…

数据库系统概述选择简答概念复习

目录 一、组成数据库的三要素 二、关系数据库特点 三、三级模式、二级映像 四、视图和审计提供的安全性 审计(Auditing) 视图(Views) 五、grant、revoke GRANT REVOKE 六、三种完整性 实体完整性 参照完整性 自定义完整性 七、事务的特性ACDI 原子性(Atomicity)…

大模型系列:提示词管理

既然大模型应用的编程范式是面向提示词的编程,需要建立一个全面且结构化的提示词库, 对提示词进行持续优化也是必不可少的,那么如何在大模型应用中更好的管理提示词呢? 1. 提示词回顾 提示词在本质上是向大型语言模型(…

基于Spring Boot的工具迭代

1. 申请git权限 2. git项目中点击我的-Settings-SSH Keys添加公钥 3. 公钥生成步骤 ssh-keygen -o -t rsa -b 4096 -C "your email" cd ~/.ssh/ cat id_rsa.pub 把公钥内容粘贴到SSH Keys 4. 创建本地分支git checkout -b branchname git远程仓库创建远程分支 …

GPT-4o的综合评估与前景展望

如何评价GPT-4o? GPT-4o作为OpenAI推出的最新一代大型语言模型,其性能、功能和应用前景都备受关注。以下是对GPT-4o的综合评估与前景展望: 一、技术性能评估 响应速度:GPT-4o在响应速度上有了显著提升,能够在极短的时间内对输入…

C++ 撤销重做

在C中实现redo/undo功能通常涉及到对命令或操作的历史进行追踪。这可以通过命令模式(Command Pattern)和内存中的栈结构来实现。命令模式允许你将操作封装为对象,这些对象可以被存储、排队、参数化、传递、调用,并且可以支持撤销&…

stm32f103 HAL库 HC-SR04测距

目录 一、实现测距二、添加TIM3控制LED根据距离以不同频率闪烁三、观察时序Modebus协议12路超声波雷达设计方案1. 系统架构设计2. 硬件设计3. 软件设计4. 通信协议设计5. 用户接口6. 安全和冗余7. 测试和验证8. 电源和物理封装9. 文档和支持 一、实现测距 配置时钟 配置定时器…

vue部署宝塔nginx配置(获取用户ip地址、反代理访问api接口、websocket转发)

以下配置为我自己的需求,因人而异,如果只是单纯的前端非交互页面,可以不用修改配置。 代码及注释,如下: #解决vue-router设置mode为history,去掉路由地址上的/#/后nginx显示404的问题location / {proxy_htt…