当前位置: 首页 > news >正文

设计模式-装饰器模式(Decorator)

设计模式-装饰器模式(Decorator)

    • 一、装饰器模式概述
      • 1.1 什么是装饰器模式
      • 1.2 简单实现装饰器模式
      • 1.3 使用装饰器模式的注意事项
    • 二、装饰器模式的用途
    • 三、装饰器模式的实现方式
      • 3.1 通过接口和抽象类实现
      • 3.2 通过Java反射实现
      • 3.3 通过使用第三方库实现

一、装饰器模式概述

1.1 什么是装饰器模式

装饰器模式是一种结构型设计模式,它允许在运行时扩展一个对象的功能,而不需要改变其现有结构。这种模式的核心思想是通过创建一个包装类(装饰器)来动态地增强或修改原有对象的行为。

具体来说,装饰器模式的主要特点如下:

  • 1、不改变原有对象的结构和方法。
  • 2、通过创建一个与被装饰对象接口相同的装饰器类,实现对被装饰对象的包装。
  • 3、可以在不改变现有代码的基础上,动态地给一个对象增加新的功能。
  • 4、装饰器模式是继承的一个补充,提供了比继承更加灵活的方式来扩展对象的行为。
    尽管装饰器模式非常灵活且可扩展,适用于需要动态地为对象增加功能的场景,但过度使用这种模式可能会导致系统的复杂性增加。因此,在使用装饰器模式时,需要确保真正需要扩展的地方使用,而不是滥用。

1.2 简单实现装饰器模式

装饰器模式是一种结构型设计模式,它允许在运行时动态地扩展一个对象的功能,而不需要改变其现有结构。下面是一个简单的 Java 实现装饰器模式的示例:

首先,我们创建一个接口 Component:

public interface Component {void operation();
}

然后,我们创建一个具体的组件类 ConcreteComponent:

public class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("具体组件的操作");}
}

接下来,我们创建一个抽象装饰器类 Decorator,它也实现了 Component 接口,并持有一个 Component 类型的对象:

public abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {component.operation();}
}

现在,我们可以创建具体的装饰器类,例如 ConcreteDecoratorA 和 ConcreteDecoratorB,它们分别在原有功能的基础上添加新的功能:

public class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}@Overridepublic void operation() {System.out.println("装饰器 A 的操作");super.operation();}
}public class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}@Overridepublic void operation() {System.out.println("装饰器 B 的操作");super.operation();}
}

最后,我们在客户端代码中使用装饰器模式:

public class Client {public static void main(String[] args) {Component component = new ConcreteComponent();Component decoratorA = new ConcreteDecoratorA(component);Component decoratorB = new ConcreteDecoratorB(decoratorA);decoratorB.operation();}
}

运行客户端代码,输出结果如下:

装饰器 B 的操作
装饰器 A 的操作
具体组件的操作

1.3 使用装饰器模式的注意事项

  • 1、装饰器模式适用于需要动态地为对象增加功能的场景,如果不需要动态扩展功能,则不必要使用装饰器模式。
  • 2、装饰器模式会增加系统的复杂性,因此应该谨慎使用,避免过度使用。
  • 3、装饰器模式要求被装饰的对象和装饰器类都必须实现相同的接口或继承相同的抽象类,否则无法进行装饰。
  • 4、装饰器模式可能会导致设计上的冗余,因为每个装饰器都需要持有一个被装饰对象的引用,这会导致系统中存在大量的引用关系。
  • 5、如果需要对多个对象进行同样的装饰操作,可以考虑使用代理模式或者享元模式来优化系统结构。

二、装饰器模式的用途

装饰器模式是一种结构型设计模式,它允许在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)。这种模式的核心在于创建一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

以下是装饰器模式的一些主要用途:

  • 1、动态地为一个对象添加新的功能,同时又不改变其结构。这可以帮助我们在不修改原有组件、接口或者类的情况下为其添加额外的功能。
  • 2、用于元类的使用情况,可以作为元类的一些简单替代方案。
  • 3、在Java AWT和Swing中广泛使用,如为按钮、文本框等组件添加新的功能。
  • 4、适用于Java I/O流,如BufferedReader、BufferedWriter等。通过装饰器模式,可以在不改变原有I/O流的基础上,为其增加新的功能。
  • 5、在Python中也有广泛应用,如GIL(Global Interpreter Lock)就是一个典型的装饰器模式的实现。

三、装饰器模式的实现方式

3.1 通过接口和抽象类实现

通过定义一个接口或抽象类,然后创建具体的装饰器类来实现装饰器模式。这种方式适用于需要动态添加功能的场景。

// 定义一个接口
public interface Component {void operation();
}// 定义一个具体组件
public class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("具体组件的操作");}
}// 定义一个抽象装饰器类
public abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {component.operation();}
}// 定义一个具体装饰器类
public class ConcreteDecorator extends Decorator {public ConcreteDecorator(Component component) {super(component);}@Overridepublic void operation() {super.operation();addedFunction();}public void addedFunction() {System.out.println("新增的功能");}
}// 客户端代码
public class Client {public static void main(String[] args) {Component component = new ConcreteComponent();Component decorator = new ConcreteDecorator(component);decorator.operation();}
}

3.2 通过Java反射实现

通过Java反射机制,可以在运行时动态地为对象添加新的功能。这种方式适用于需要根据条件动态改变行为的场景。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class DecoratorDemo {public static void main(String[] args) {MyInterface myInterface = (MyInterface) Proxy.newProxyInstance(MyInterface.class.getClassLoader(),new Class[]{MyInterface.class},new DecoratorInvocationHandler(new MyInterfaceImpl()));myInterface.doSomething();}
}interface MyInterface {void doSomething();
}class MyInterfaceImpl implements MyInterface {@Overridepublic void doSomething() {System.out.println("原始方法");}
}class DecoratorInvocationHandler implements InvocationHandler {private Object target;public DecoratorInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("装饰器开始执行");Object result = method.invoke(target, args);System.out.println("装饰器结束执行");return result;}
}

3.3 通过使用第三方库实现

有一些第三方库提供了装饰器模式的实现,如Spring框架中的AOP(面向切面编程)模块。这些库通常提供了更加完善的功能和更好的性能。

http://www.lryc.cn/news/223216.html

相关文章:

  • Java 数据结构篇-实现双链表的核心API
  • 电脑如何截屏?一起来揭晓答案!
  • 【实战-08】flink 消费kafka自定义序列化
  • 深入浅出 Django 异步编程
  • 力扣 138. 随机链表的复制
  • STM32外部中断大问题
  • FPGA配置采集AR0135工业相机,提供2套工程源码和技术支持
  • KubeSphere v3.4.0 部署K8S Docker + Prometheus + grafana
  • Codeforces Round 908 (Div. 2)题解
  • Redis笔记 Redis主从同步
  • 数据结构-Prim算法构造无向图的最小生成树
  • MFC串口通信(SerialPort)
  • Vim基本使用操作
  • 【深蓝学院】手写VIO第8章--相机与IMU时间戳同步--作业
  • Naocs配置中心配置映射List、Map、Map嵌套List等方式
  • 如何通过CRM系统进行销售机会管理?
  • 解决idea启动tomcat控制台中文乱码
  • vscode + cmake + opencv example
  • day57【动态规划】647.回文子串 516.最长回文子序列
  • 分享vmware和Oracle VM VirtualBox虚拟机的区别,简述哪一个更适合我?
  • YOLOV5模型运行
  • @Autowired和@Resource注解的区别和联系
  • 设计模式类型
  • Android修行手册-实现利用POI将图片插入到Excel中(文末送书)
  • 低功耗工业RFID设备应用
  • # Oracle 库常见问题排查
  • 矩阵乘积的迹对矩阵求导
  • IP 地址冲突检测工具
  • js树形数组遍历练习,扁平化、格式化、获取节点父级
  • c语言贪吃蛇项目的实现