Java设计模式 十 装饰模式 (Decorator Pattern)

embedded/2025/1/23 11:17:37/

装饰模式 (Decorator Pattern)

装饰模式是一种结构型设计模式,它的作用是动态地为对象添加额外的职责,而不修改其代码结构。装饰模式通过创建装饰类,将核心功能与附加功能分离,使得代码更灵活,更具扩展性。


1. 装饰模式的组成

装饰模式包含以下角色:

  • Component(抽象组件): 定义对象的通用接口,可以动态地为该接口添加职责。
  • ConcreteComponent(具体组件): 组件的具体实现,是最基础的对象。
  • Decorator(装饰器): 持有一个 Component 的引用,并定义一个与 Component 一致的接口。
  • ConcreteDecorator(具体装饰器): 实现具体的装饰功能,同时调用组件的核心功能。

2. 装饰模式的优点

  1. 功能扩展灵活: 可以动态地为对象添加功能,而不需要修改原有类。
  2. 遵循开闭原则: 增加功能时,无需修改已有代码,只需增加新的装饰器类。
  3. 细粒度控制: 每个装饰器只负责一个特定的功能,职责单一。

3. 装饰模式的缺点

  1. 增加复杂性: 每个装饰器都是一个新的类,可能导致类数量增加。
  2. 调试困难: 如果多个装饰器嵌套使用,可能会导致调试和排错复杂化。

4. 装饰模式的实现

场景示例:给文本添加装饰功能

需求: 假设我们有一个文本处理组件,支持基本的文本输出功能。现在需要为它动态添加功能,比如加粗、斜体、添加颜色等。


1) 定义抽象组件

抽象组件定义通用接口,表示所有文本处理组件的公共行为。

java">// 抽象组件
public interface Text {String render(); // 渲染文本
}

2) 实现具体组件

具体组件实现基本的文本渲染功能。

java">// 具体组件
public class PlainText implements Text {private String content;public PlainText(String content) {this.content = content;}@Overridepublic String render() {return content;}
}

3) 定义装饰器

装饰器类持有一个 Text 的引用,负责为组件动态添加功能。

java">// 抽象装饰器
public abstract class TextDecorator implements Text {protected Text text;public TextDecorator(Text text) {this.text = text;}@Overridepublic String render() {return text.render();}
}

4) 实现具体装饰器

具体装饰器负责添加不同的功能,例如加粗和斜体。

java">// 加粗装饰器
public class BoldText extends TextDecorator {public BoldText(Text text) {super(text);}@Overridepublic String render() {return "<b>" + super.render() + "</b>";}
}// 斜体装饰器
public class ItalicText extends TextDecorator {public ItalicText(Text text) {super(text);}@Overridepublic String render() {return "<i>" + super.render() + "</i>";}
}// 颜色装饰器
public class ColoredText extends TextDecorator {private String color;public ColoredText(Text text, String color) {super(text);this.color = color;}@Overridepublic String render() {return "<span style='color:" + color + "'>" + super.render() + "</span>";}
}

5) 客户端代码

客户端可以自由组合不同的装饰器来扩展功能。

java">public class Client {public static void main(String[] args) {// 基础文本Text text = new PlainText("Hello, World!");// 添加加粗功能Text boldText = new BoldText(text);// 添加斜体功能Text italicText = new ItalicText(boldText);// 添加颜色功能Text coloredText = new ColoredText(italicText, "red");// 渲染最终文本System.out.println(coloredText.render());}
}

运行结果:
<span style='color:red'><i><b>Hello, World!</b></i></span>

最终输出的文本是带有颜色、加粗和斜体的 HTML 格式。


5. 装饰模式的应用场景

  1. 动态扩展功能:
    需要为对象动态添加功能,并且可能在运行时组合多种功能。

  2. 代替继承:
    使用装饰模式可以避免通过继承实现功能扩展,减少类的数量。

  3. 需要根据不同需求组合功能:
    比如 GUI 系统中的组件,可能需要动态添加滚动条、边框、阴影等功能。


6. Java 中的典型应用

  1. java.io 包中的装饰器模式

    • InputStreamOutputStream 类的子类:
      • BufferedInputStream
      • DataInputStream
      • FilterInputStream
    • 通过装饰器动态扩展流的功能:
      java">InputStream input = new FileInputStream("file.txt");
      InputStream bufferedInput = new BufferedInputStream(input);
      
  2. Java Swing

    • Java Swing 的组件可以动态添加边框等效果:
      java">JTextField textField = new JTextField();
      textField.setBorder(BorderFactory.createLineBorder(Color.BLACK));
      

7. 装饰模式与其他模式的比较

模式主要用途与装饰模式的区别
代理模式控制对象的访问代理模式不改变对象的功能,装饰模式增加新功能。
适配器模式接口不兼容的对象协同工作适配器模式主要解决接口问题,装饰模式动态增强功能。
桥接模式分离抽象和实现桥接模式关注结构设计,装饰模式关注动态增强功能。

8. 总结

装饰模式是一种灵活、优雅的设计模式,它通过组合的方式动态为对象添加功能,而不修改原有代码。装饰模式遵循开闭原则,是功能扩展需求中的理想选择。

在实际开发中,装饰模式广泛应用于流处理、GUI 系统以及其他需要动态功能扩展的场景。它是一种高效且值得掌握的设计模式


http://www.ppmy.cn/embedded/156288.html

相关文章

博客之星2024年度总评选——我的年度创作回顾与总结

2024年&#xff0c;是我在CSDN博客上持续耕耘、不断成长的一年。在此&#xff0c;与大家分享一下我的年度创作回顾与总结。 一、创作成长与突破 在人工智能领域&#xff0c;技术迭代迅速&#xff0c;知识更新频繁。为了保持自己的竞争力&#xff0c;在今年&#xff0c;我始终…

让旅游更智能:基于AR的旅游导览应用解析

友友们好! 我的新专栏《Python进阶》正式启动啦!这是一个专为那些渴望提升Python技能的朋友们量身打造的专栏,无论你是已经有一定基础的开发者,还是希望深入挖掘Python潜力的爱好者,这里都将是你不可错过的宝藏。 在这个专栏中,你将会找到: ● 深入解析:每一篇文章都将…

循环队列(C语言)

从今天开始我会开启一个专栏leetcode每日一题&#xff0c;大家互相交流代码经验&#xff0c;也当作我每天练习的自我回顾。第一天的内容是leetcode622.设计循环队列。 一、题目详细 设计你的循环队列实现。 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#…

GS论文阅读--Hard Gaussian Splatting

前言 本文也是对高斯点云的分布进行优化的&#xff0c;看&#xff01; 文章目录 前言1.背景介绍2.关键内容2.1 位置梯度驱动HGS2.2 渲染误差引导HGS 3.文章贡献 1.背景介绍 在训练过程中&#xff0c;它严重依赖于视图空间位置梯度的平均幅度来增长高斯以减少渲染损失。然而&…

使用 Helm 安装 Redis 集群

在 Kubernetes 集群中使用 Helm 安装 Redis 集群可以极大地简化部署和管理 Redis 的过程。本文将详细介绍如何使用 Helm 安装 Redis 集群&#xff0c;并提供一些常见问题的解决方案。 前提条件 Kubernetes 集群。&#xff08;略&#xff09;已安装 Helm 工具。搭建了存储类nf…

【统计信号处理基础——估计与检测理论】Vol1.Ch2. 最小方差无偏估计

系列目录 【统计信号处理基础——估计与检测理论】Vol1.Ch1. 引言 文章目录 1. 无偏估计量2. 最小方差准则3. 最小方差无偏估计的存在性4. 求最小方差无偏估计量5. 扩展到矢量参数习题2.12.22.32.42.52.6 本章寻找未知确定性参数的好的估计量。我们将注意力限制在通过平均产生真…

5G 核心网 相关概念快速入门

在我们开始阅读3GPP协议来学习5G核心网之前&#xff0c; 不妨来看看我之前整理的PPT&#xff0c;快速学习核心网相关概念&#xff0c; 以及5G转发面PFCP协议的相关核心知识。 涵盖了最精简的核心骨干内容&#xff0c;助你轻松上阵。 讲解目标 3GPP和相关协议 5G核心网架构模…

云原生作业(四)

简述mysql 主从复制原理及其工作过程&#xff0c;配置一主两从并验证。 主从复制原理 主从原理&#xff1a;MySQL 主从同步是一种数据库复制技术&#xff0c;它通过将主服务器上的数据更改复制到一个或多个从服务器&#xff0c;实现数据的自动同步。 主从同步的核心原理是将…