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

文章目录

类图: 装饰器设计模式类图

一.什么是装饰器设计模式?

装饰器模式 (Decorator Pattern) 是一种结构型设计模式。它允许在运行时动态地为对象添加新的功能,而无需修改其代码。装饰器模式通过将对象嵌套在装饰器对象中,实现了功能的动态扩展,同时遵循了开放-关闭原则。

二.装饰器模式的特点

  • 运行时动态扩展:通过嵌套装饰器对象,可以动态地为对象增加功能。
  • 与继承的区别:装饰器通过组合来扩展对象功能,而不是通过继承,避免了类爆炸问题。
  • 灵活性:可以使用多个装饰器类,按照需要灵活组合功能。

三.装饰器模式的结构

  • Component(组件接口):定义一个对象接口,可以动态地为其增加职责。
  • ConcreteComponent(具体组件):实现基础功能的类。
  • Decorator(抽象装饰器):实现 Component 接口,并包含一个指向 Component 对象的引用。
  • ConcreteDecorator(具体装饰器) :实现额外的功能,并调用组件对象的原有功能。

四.装饰器模式的优缺点

  • 优点:
    • 动态扩展:可以动态地为对象添加功能。
    • 遵循开放-关闭原则:无需修改原有类的代码即可扩展功能。
    • 灵活性:装饰器可以灵活组合,扩展方式更具弹性。
  • 缺点:
    • 复杂性增加:使用多个装饰器会导致类数量增多,结构变得复杂。
    • 调试困难:由于功能是动态组合的,调试时可能难以定位问题来源。

五.装饰器模式的 C++ 实现

cpp 复制代码
#include <iostream>
#include <memory>
using namespace std;

// 抽象组件
class Component {
public:
    virtual void Operation() const = 0;
    virtual ~Component() = default;
};

// 具体组件
class ConcreteComponent : public Component {
public:
    void Operation() const override {
        cout << "ConcreteComponent: Performing operation." << endl;
    }
};

// 抽象装饰器
class Decorator : public Component {
protected:
    shared_ptr<Component> component; // 持有组件的引用
public:
    Decorator(shared_ptr<Component> comp) : component(move(comp)) {}
    void Operation() const override {
        if (component) {
            component->Operation();
        }
    }
};

// 具体装饰器A
class ConcreteDecoratorA : public Decorator {
public:
    ConcreteDecoratorA(shared_ptr<Component> comp) : Decorator(move(comp)) {}
    void Operation() const override {
        Decorator::Operation(); // 调用原始组件的功能
        AddedBehavior();        // 添加新行为
    }
private:
    void AddedBehavior() const {
        cout << "ConcreteDecoratorA: Adding behavior A." << endl;
    }
};

// 具体装饰器B
class ConcreteDecoratorB : public Decorator {
public:
    ConcreteDecoratorB(shared_ptr<Component> comp) : Decorator(move(comp)) {}
    void Operation() const override {
        Decorator::Operation(); // 调用原始组件的功能
        AddedBehavior();        // 添加新行为
    }
private:
    void AddedBehavior() const {
        cout << "ConcreteDecoratorB: Adding behavior B." << endl;
    }
};

// 客户端代码
int main() {
    shared_ptr<Component> simple = make_shared<ConcreteComponent>();
    cout << "Client: Using a simple component:" << endl;
    simple->Operation();

    shared_ptr<Component> decoratorA = make_shared<ConcreteDecoratorA>(simple);
    cout << "\nClient: Using a component decorated with A:" << endl;
    decoratorA->Operation();

    shared_ptr<Component> decoratorB = make_shared<ConcreteDecoratorB>(decoratorA);
    cout << "\nClient: Using a component decorated with A and B:" << endl;
    decoratorB->Operation();

    return 0;
}

六.装饰器模式的 Java 实现

java 复制代码
// 抽象组件
interface Component {
    void operation();
}

// 具体组件
class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("ConcreteComponent: Performing operation.");
    }
}

// 抽象装饰器
abstract class Decorator implements Component {
    protected Component component;

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

    @Override
    public void operation() {
        if (component != null) {
            component.operation();
        }
    }
}

// 具体装饰器A
class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation(); // 调用原始组件的功能
        addedBehavior();
    }

    private void addedBehavior() {
        System.out.println("ConcreteDecoratorA: Adding behavior A.");
    }
}

// 具体装饰器B
class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation(); // 调用原始组件的功能
        addedBehavior();
    }

    private void addedBehavior() {
        System.out.println("ConcreteDecoratorB: Adding behavior B.");
    }
}

// 客户端代码
public class DecoratorPatternExample {
    public static void main(String[] args) {
        Component simple = new ConcreteComponent();
        System.out.println("Client: Using a simple component:");
        simple.operation();

        Component decoratorA = new ConcreteDecoratorA(simple);
        System.out.println("\nClient: Using a component decorated with A:");
        decoratorA.operation();

        Component decoratorB = new ConcreteDecoratorB(decoratorA);
        System.out.println("\nClient: Using a component decorated with A and B:");
        decoratorB.operation();
    }
}

七.代码解析

  • 抽象组件(Component)
    • 提供统一接口 Operation,供所有具体组件和装饰器实现。
    • 使得客户端代码可以以相同的方式使用组件和装饰器。
  • 具体组件(ConcreteComponent)
    • 实现基础功能,例如打印操作信息。
  • 抽象装饰器(Decorator)
    • 持有一个 Component 类型的指针,代表被装饰的对象。
    • 定义通用的装饰行为,默认直接调用被装饰对象的 Operation 方法。
  • 具体装饰器(ConcreteDecoratorA/B)
    • 通过扩展 Decorator 类,增加特定功能。
    • AddedBehavior 方法实现装饰器的额外行为,例如打印装饰信息。
  • 使用 shared_ptr
    • 动态管理对象内存,避免手动管理导致的内存泄漏。

八.总结

装饰器模式提供了一种灵活的方式来动态扩展对象的功能,避免了继承导致的类膨胀问题。通过引入抽象装饰器和具体装饰器,装饰器模式实现了功能的动态组合,使得代码更易于维护和扩展。
应用场景:

  • 动态扩展对象功能:需要在不修改对象代码的情况下,为对象添加功能。
  • 替代子类扩展:避免因为子类扩展功能导致的类爆炸问题。
  • 灵活组合功能:需要根据不同的条件动态组合对象的功能。
相关推荐
惊涛骇浪、6 分钟前
SpringMVC + Tomcat10
java·tomcat·springmvc
墨染点香19 分钟前
LeetCode Hot100【6. Z 字形变换】
java·算法·leetcode
ldj202042 分钟前
SpringBoot为什么使用new RuntimeException() 来获取调用栈?
java·spring boot·后端
超龄超能程序猿42 分钟前
Spring 应用中 Swagger 2.0 迁移 OpenAPI 3.0 详解:配置、注解与实践
java·spring boot·后端·spring·spring cloud
风象南1 小时前
SpringBoot配置属性热更新的轻量级实现
java·spring boot·后端
洛阳泰山1 小时前
Spring Boot 整合 Nacos 实战教程:服务注册发现与配置中心详解
java·spring boot·后端·nacos
Y4090011 小时前
C语言转Java语言,相同与相异之处
java·c语言·开发语言·笔记
YuTaoShao1 小时前
【LeetCode 热题 100】994. 腐烂的橘子——BFS
java·linux·算法·leetcode·宽度优先
布朗克1681 小时前
java常见的jvm内存分析工具
java·jvm·数据库
都叫我大帅哥2 小时前
深入浅出 Resilience4j:Java 微服务的“免疫系统”实战指南
java·spring cloud