java中设计模式之装饰模式(结构型模式)

2023-10-26

什么是装饰模式?

装饰模式(Decorator Pattern)是一种结构型设计模式,它允许你在不改变已有对象结构的情况下,动态地向对象添加新的功能。

装饰模式利用组合和继承的方式,通过创建包装对象来包裹原始对象,以增强其功能。这样可以在不修改原有对象的情况下,通过添加装饰器类来对对象进行功能扩展。

以下是装饰模式的几个角色:

  1. Component(抽象构件):定义了一个抽象接口,即原始对象和装饰器类的共同接口。可以是一个抽象类或接口。

  2. ConcreteComponent(具体构件):实现了Component接口的具体对象,是被装饰的原始对象。

  3. Decorator(装饰器):继承自Component,并持有一个Component对象的引用。装饰器的作用是扩展Component的功能,实现对原始对象的包装,并在调用原始对象前后添加额外的逻辑。

  4. ConcreteDecorator(具体装饰器):继承自Decorator,具体实现对Component对象的扩展功能。可以有多个具体装饰器类,它们可以按需组合使用。

通过装饰模式,可以动态地给对象添加功能,而不是通过继承进行静态的功能扩展。这样可以避免类的爆炸式增长,同时使得代码更加灵活和可扩展。

代码实例

//组件接口
interface Car {
    void assemble();
}
//具体组件类
class BasicCar implements Car {
    @Override
    public void assemble() {
        System.out.println("基础车辆组装");
    }
}
//装饰器类
abstract class CarDecorator implements Car {
    protected Car car;
    public CarDecorator(Car car) {
        this.car = car;
    }
    @Override
    public void assemble() {
        car.assemble();
    }
}
// 具体装饰器类
class SportsCar extends CarDecorator {
    public SportsCar(Car car) {
        super(car);
    }
    @Override
    public void assemble() {
        super.assemble();
        System.out.println("增加运动车套件");
    }
}
// 具体装饰器类
class LuxuryCar extends CarDecorator {
    public LuxuryCar(Car car) {
        super(car);
    }
    @Override
    public void assemble() {
        super.assemble();
        System.out.println("增加豪华配置");
    }
}
// 在客户端使用装饰模式
public class Client {
    public static void main(String[] args) {
        Car basicCar = new BasicCar();
        Car sportsCar = new SportsCar(basicCar);
        sportsCar.assemble();
        Car luxurySportsCar = new LuxuryCar(sportsCar);
        luxurySportsCar.assemble();
    }
}

在上述代码中,基础构建是被装饰的原始对象,而装饰器A和装饰器B是具体的装饰器类。通过将装饰器对象包裹在原始对象周围,我们可以动态地为原始对象添加新的行为,而无需改变其结构。在调用原始对象的操作之前和之后,装饰器可以执行额外的操作。

装饰模式在许多情况下都被广泛应用,例如Java中的I/O流、GUI组件等。它提供了一种灵活且可扩展的方式来修改对象的行为,同时遵循开闭原则(对扩展开放,对修改关闭)。

注意:

  1. 装饰器类需要实现与被装饰对象相同的接口,以便可以对被装饰对象进行包装。
  2. 装饰器类应该在调用被装饰对象的方法之前或之后添加新的行为。
  3. 不要创建过多的装饰器对象,否则会导致代码变得复杂难以维护。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中设计模式之装饰模式(结构型模式) 的相关文章

  • 包 javax.comm 不存在[重复]

    这个问题在这里已经有答案了 可能的重复 如何获取javax comm API https stackoverflow com questions 7562565 how to get javax comm api 我已经下载并安装了jdk1
  • Import 语句顺序有什么影响吗?

    这个疑问由来已久 当我使用 eclipse 编写类时 导入语句会自动填充 import语句的顺序有影响吗 1 关于编程执行速度 2 任何标准编码实践都是相同的 import语句对执行速度没有影响at all 它们仅在编译时重要 如果您完全限
  • 翻转旋转和图像

    我正在用 Java 编写一个平台游戏 并且正在手动编码玩家动画 我分别为每个肢体设置动画 改变位置和旋转 当玩家面向右时 这工作得很好 但是当玩家面向左时 我不知道如何处理旋转 以使它们在玩家向左转时看起来相同 每个身体部位的位置都是相对于
  • 在 eclipse indigo 中找不到 Window builder pro

    我读到 Eclipse Indigo 安装了 Window Builder Pro 插件 但我不知道它在哪里 文件 新建 项目没有给我选择 Window Builder Pro 的选项 如何找到它 您需要将此更新站点添加到 Eclipse
  • java中使用awt.Toolkit和Clipboard是否可以知道剪贴板中复制的内容是否是mp3文件

    我正在尝试编写一个运行于背景 and monitors复制 a 的复制操作 mp3 file or a 文件夹包含 a mp3 file Clipboard cb Toolkit getDefaultToolkit getSystemCli
  • 如何为流数据创建 Flux/Publisher

    我正在使用轮询方法定期获取数据 新数据可能随时到达 我想向我的客户公开一个反应式接口 因此 我想创建一个发布者 Flux 它会在新数据可用时发布新数据并通知订阅者 我怎么做 我看到的所有 Flux 示例都是针对数据已知 可用的情况 实际上
  • 有人在实际应用程序中使用短和字节原始类型吗?

    我自 2004 年以来一直使用 Java 进行编程 主要是企业和 Web 应用程序 但我从来没有用过short or byte 而不是只是为了了解这些类型如何工作的玩具程序 即使在一个for loop100次 我们通常会选择int 我不记得
  • Hibernate/JPA 在启动时不验证数据库架构

    由于某种原因 hibernate 无法捕获诸如将实体映射到不存在的表之类的问题 我的 persistence xml 文件看起来像这样
  • java列表中的addAll方法

    我一直在研究java中的addAll方法 但这让我感到奇怪 到底有什么区别public void addAll List
  • 为什么在步骤中将 TransactionManager 设置为 JPATransactionManager 不正确?

    我正在使用 Spring Batch 和 JPA 并且经历了 TransactionManager bean 冲突 我通过在步骤中将 TransactionManager 设置为 JpaTransactionManager 找到了解决方案
  • 在 CSS 中设置 TableView 样式 (JavaFX)

    如何在 TableView 中设置 THIS 点的样式 我的 CSS 代码如下所示 Empty Stylesheet file root fx background color 262626 table view fx background
  • 如何使用 Jackson 重命名 JSON 序列化中的根密钥

    我正在使用 Jackson 对对象列表进行 JSON 序列化 这是我得到的 ArrayList id 1 name test name 但我想要这个 rootname id 1 name test name ie showing the s
  • 从MySQL php中的特定列获取最大ID和最小ID

    我是新来的php现在尝试从中检索数据MySQL到安卓 这是我的工作细节 table In 检索总小时数函数 我想检索最短 ID 时间 and 最大 ID 超时 from MySQL到安卓通过php最后使用下面的代码来获取总小时数 假设 ID
  • 为什么 getSession() 在短时间内间隔的后续请求中不返回相同的会话?

    我正在发送一个 getJSON HTTP GET 请求两次 使用不同的数据 一次又一次 假设我们有 request1 和 request2 我可以在 FF 和 Chrome 的开发者工具中看到我有相同的cookie JSESSIONID F
  • 使用 java 执行 Matlab 函数

    我正在编写一个应用程序 它使用 matlab 进行图像处理 然后使用 Java 接口显示结果 由于某些原因 我必须同时使用 Java 和 Matlab 如何在java中使用matlab函数 如何创建和访问界面 MATLAB控制 http m
  • 对需要强制转换的 Java 泛型感到困惑

    我对以下代码感到困惑 import java util ArrayList import java util LinkedList import java util List public class GenericsTest
  • 封闭实例的匿名类

    我正在阅读 Joshua Bloch 的 Effective Java 第二版 目前我在第 22 项 它描述了内部类和嵌套类 但我无法理解他这句话的意思 匿名类具有封闭实例当且仅当它们发生时 在非静态上下文中 有人能给我一个代码示例并解释它
  • 如何在 SnakeYaml 中解析 YAML 文件的一部分

    我是 YAML 新手 并且解析了一个 YAML 配置文件 如下所示 applications authentication service version 2 0 service url https myapp corp auth app
  • TextView 用字母打乱了我的话

    我的要求 创建 传入气泡 其宽度按内容排列 最大宽度为 90 我有这个标记
  • Java无限信号量

    想知道如何not使用信号量限制连接 或任何东西 所以你可能会想 这听起来很愚蠢 但是 它稍微简化了我的代码 因为它让我可以统一处理有限和无限的情况 请注意 我并不是在寻找有关如何编写类似内容的建议 if limited semaphore

随机推荐