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中设计模式之装饰模式(结构型模式) 的相关文章

  • WebSphere 中跨 JVM 的会话复制

    我们建立了一个基础设施 其中网络服务器是集群的 而应用程序服务器不是 Web 服务器根据循环策略将请求路由到应用程序服务器 在这种情况下 一个应用程序服务器中可用的会话数据在另一应用程序服务器中不可用 无论如何 是否可以使来自第一个应用程序
  • 中断并标签,“标签 MyLabel 丢失”

    我有这样的代码 if condition1 break MyLabel while true some code here MyLabel if condition2 break more code here 我收到此错误 标签 MyLab
  • 在 spring-boot 中设置 base-href 和 context-path - Angular 6 应用程序

    我正在构建一个 Web 应用程序 其中 UI 客户端组件是使用 Angular 6 构建的 后端 服务器端 位于 Spring boot 上 申请预计可在 http localhost 8080 FUtility 我通过在 appmodul
  • Java EE 6 和单例

    谁能解释一下在 Java EE 6 应用程序中实现 Singleton 的完整过程 我假设我不应该以声明静态变量的典型方式创建单例 而应该使用 Singleton注解 我必须这样做吗 难道只是声明一下的情况 Singleton就是这样 我还
  • 如何在JavaFX中有效地滚动和缩放大图像?

    作为图像处理应用程序的一部分 我需要创建具有缩放 滚动和矢量叠加功能的简单查看器模块 图像相当大 40000x20000 这使得 ImageView 上的操作变慢 缓冲等 在 JavaFX 中处理巨大图像时 改善用户体验的最佳选项是什么 我
  • Glassfish 4 - JDBC 领域

    Glassfish 4 中的密码加密算法和摘要算法有什么区别 因为Password加密算法不能为空 所以我使用了MD5 Encoding使用了Hex 摘要算法为空 因此默认为 SHA 256 但是 如果我使用 JAAS 制作一个简单的登录应
  • 有没有办法让Maven自动下载快照版本?

    所以我有一个项目依赖于另一个项目的快照版本 依赖关系是
  • Android:TelephonyManager 类

    我不明白为什么 API 文档中这么写TelephonyManager类是public 但是当我尝试创建一个实例时 它说它不是公共类 并且无法从包中访问 我看到它也说使用Context getSystemService Context TEL
  • 我可以使用 Selenium Webdriver 测试元素的顺序吗?

    有一个表单 其中有 3 个字段 具有 3 个不同的 ID fieldset div div fieldset
  • Java 8 Stream - 并行执行 - 不同的结果 - 为什么?

    假设我有一个List
  • java中永远不会出现的异常

    我为点和向量编写一个类 我想用它们来计算向量的点和范数 这些是点类和向量类 public class Point public float x y public class MyVector public Point start end 我
  • 用于 Eclipse 的 Resharper [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 将 Maven 控制台与 m2eclipse 一起使用

    Maven 新手在这里 有没有办法在 Eclipse 中打开控制台并在 M2Eclipse 插件上执行 Maven 命令 这是一个非常好的插件 但我环顾四周 没有找到我想要的一些功能 谢谢 如果你想运行特定的maven插件 你可以这样做 g
  • JavaFX Integer Spinner (IntegerSpinnerValueFactory) 不会将值回绕到最小值

    我创建了一个带有值的整数微调器 min 5 max 15 and initialValue 12 and wrapAround true 一旦旋转器到达max 15 增量期间的值 而不是将值重置为min 5 正如它所说文档 https op
  • gwt 文本框添加更改处理程序

    我有一个从设计师那里收到的文本框 但是我在 GWT 中编写了操作 问题是文本框为空 但是当通过按下按钮用值填充文本框时 将显示警报框 通知值已更改 但没有成功 帮助我 TextBox zip1 null function onModuleL
  • 如何从 Sublime Text 编辑器调试 Java 应用程序

    有时我正在对相当大的 Java 应用程序进行简单的修复 但我不想打开 Eclipse 来执行此任务 Eclipse 启动时间很长 并且由于该项目是由大量子项目构建的 而这些子项目无论如何都是由 Maven 构建的 因此需要很长时间才能使用
  • 在Java内存管理中,“PS”代表什么?

    每当我看到 Java 中对内存的引用时 各种空格总是以 PS 为前缀 PS 是什么意思 它开始困扰我 到目前为止我唯一的猜测是 泳池空间 但这将是多余的 例子 PS伊甸园空间 PS 幸存者空间 PS 终身空间 老一代 PS Perm Gen
  • 没有运算符与给定名称和参数类型匹配。您可能需要添加显式类型转换。 -- Netbeans、Postgresql 8.4 和 Glassfish

    我正在尝试使用 EclipseLink 在 Glassfish 中使用 JPA 编辑 Postgresql 中的表 当我插入一个实体时 它运行良好 但是 当我尝试编辑或删除同一实体时 它失败并出现以下错误 任何想法 Caused by Ex
  • Volley 在第一次调用方法时返回 null

    我正在尝试使用 volley 从服务器检索数据 但是当我第一次调用此方法时 我收到服务器的响应 但该方法返回 null 如果我第二次调用它 我会得到最后的响应 public String retrieveDataFromServer Str
  • removeall 和removeif 的用例

    我找到了这个 fun main val list MutableList

随机推荐