【设计模式-装饰】

定义

装饰模式是一种结构型设计模式,它允许在不改变对象自身的前提下动态地给对象添加职责(功能)。通过使用装饰模式,可以将对象的功能扩展变得更加灵活和可维护,同时避免了类继承的复杂性。

特点

  • 动态扩展对象功能:装饰模式可以在运行时动态地为对象添加新的功能,而不影响其他对象。
  • 遵循开闭原则:装饰模式可以通过组合来扩展对象功能,而不是通过修改类定义,从而遵循开闭原则。
  • 灵活性强:多个装饰者可以自由组合,为对象添加不同的功能。

组成

装饰模式由以下几个部分组成:

  • 组件接口(Component):定义了对象的通用接口,可以被具体的组件和装饰者类实现。
  • 具体组件(Concrete Component):实现组件接口的类,表示可以被装饰的原始对象。
  • 装饰器接口(Decorator):实现了组件接口,并持有一个组件对象的引用,用于对该对象进行装饰。
  • 具体装饰器(Concrete Decorator):扩展装饰器类,实现额外的功能,并可以调用被装饰对象的原始功能。

UML图

代码

组件接口

java 复制代码
// 组件接口,定义通用的操作方法
public interface Component {
    void operation();
}

具体组件

java 复制代码
// 具体组件,实现了组件接口,表示可以被装饰的原始对象
public class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("ConcreteComponent: Performing operation.");
    }
}

装饰器抽象类

java 复制代码
// 装饰器类,实现了组件接口,并持有一个组件对象的引用
public abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation(); // 调用原始对象的操作
    }
}

具体装饰器

java 复制代码
// 具体装饰器A,为组件添加额外的功能
public class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation(); // 调用原始操作
        addedBehaviorA();  // 添加额外的功能
    }

    // 装饰器A的附加功能
    private void addedBehaviorA() {
        System.out.println("ConcreteDecoratorA: Adding behavior A.");
    }
}

// 具体装饰器B,为组件添加另外的功能
public class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation(); // 调用原始操作
        addedBehaviorB();  // 添加额外的功能
    }

    // 装饰器B的附加功能
    private void addedBehaviorB() {
        System.out.println("ConcreteDecoratorB: Adding behavior B.");
    }
}

client

java 复制代码
public class DecoratorPatternExample {
    public static void main(String[] args) {
        // 创建原始组件对象
        Component component = new ConcreteComponent();

        // 使用装饰器A进行装饰
        Component decoratedComponentA = new ConcreteDecoratorA(component);
        decoratedComponentA.operation();
        System.out.println();

        // 使用装饰器B进行装饰
        Component decoratedComponentB = new ConcreteDecoratorB(component);
        decoratedComponentB.operation();
        System.out.println();

        // 使用装饰器A和B进行多重装饰
        Component decoratedComponentAB = new ConcreteDecoratorB(decoratedComponentA);
        decoratedComponentAB.operation();
    }
}

优点

  • 灵活扩展功能:可以在运行时动态地为对象添加新功能,而无需修改类的定义或继承类。
  • 遵循开闭原则:通过组合而不是继承来扩展对象功能,使得系统更具扩展性。
  • 减少子类数量:避免了通过继承来扩展功能的情况,减少了系统中类的数量和复杂性。

缺点

  • 增加复杂性:由于装饰器和原始组件都实现了相同的接口,可能会导致系统中对象的层次结构变得复杂,尤其是多重装饰时。
  • 依赖细节:装饰器依赖于被装饰的组件接口,可能会导致依赖关系复杂化,特别是在多层装饰的情况下。

场景

  • 需要动态扩展对象功能:当需要在运行时为对象添加或修改功能时,可以使用装饰模式。
  • 替代继承:当不想通过继承来扩展类的功能,或无法通过继承(如第三方库中的类不能修改)时,可以使用装饰模式。
  • 需要对对象进行多重装饰:当对象需要被多次装饰,以不同的方式扩展功能时,可以使用装饰模式。

总结

装饰模式提供了一种灵活且可扩展的方式来为对象添加功能,避免了类继承的复杂性和局限性。通过将对象和装饰器组合,可以在运行时动态地为对象添加不同的功能,从而使系统更加灵活和可维护。然而,装饰模式也可能增加系统的复杂性,尤其是在多层装饰的情况下,因此需要在设计时进行权衡。

相关推荐
boligongzhu几秒前
DALSA工业相机SDK二次开发(图像采集及保存)C#版
开发语言·c#·dalsa
Eric.Lee2021几秒前
moviepy将图片序列制作成视频并加载字幕 - python 实现
开发语言·python·音视频·moviepy·字幕视频合成·图像制作为视频
Ttang231 分钟前
Tomcat原理(6)——tomcat完整实现
java·tomcat
7yewh3 分钟前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux
钱多多_qdd12 分钟前
spring cache源码解析(四)——从@EnableCaching开始来阅读源码
java·spring boot·spring
waicsdn_haha14 分钟前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
_WndProc16 分钟前
C++ 日志输出
开发语言·c++·算法
Q_192849990624 分钟前
基于Spring Boot的摄影器材租赁回收系统
java·spring boot·后端
qq_4335545425 分钟前
C++ 面向对象编程:+号运算符重载,左移运算符重载
开发语言·c++
Code_流苏27 分钟前
VSCode搭建Java开发环境 2024保姆级安装教程(Java环境搭建+VSCode安装+运行测试+背景图设置)
java·ide·vscode·搭建·java开发环境