装饰器模式(Decorator Pattern)

装饰器模式(Decorator Pattern)


定义

装饰器模式是一种结构性设计模式,通过 动态组合对象 的方式,为对象添加额外功能,而无需修改原有类。


装饰器模式的核心思想
  1. 对象增强:在现有类的基础上动态添加功能,而不修改类的代码。
  2. 功能组合:通过多个装饰器的嵌套,可以灵活组合功能。
  3. 继承与组合
    • 继承是一种 静态扩展
    • 装饰器模式是一种 动态扩展

类结构

装饰器模式的类结构包含以下几部分:

  1. 抽象组件(Component)

    • 定义接口,声明核心功能方法。
    • 所有被装饰类和装饰器类都必须实现此接口。
  2. 具体组件(ConcreteComponent)

    • 实现抽象组件的接口,定义基本功能。
  3. 装饰器基类(Decorator)

    • 实现抽象组件接口。
    • 持有一个组件的引用(指针),并通过组合扩展功能。
  4. 具体装饰器类(ConcreteDecorator)

    • 从装饰器基类派生。
    • 对原始功能进行增强。

装饰器模式与代理模式的区别
区别点 装饰器模式 代理模式
目的 增强类的功能 控制访问权限
实现的重点 功能扩展 权限控制
类的设计 装饰器类持有被装饰对象的指针 代理类持有被代理对象的指针
调用顺序 递归调用,逐层增强功能 代理类决定是否调用实际方法

应用场景
  1. 需要动态扩展功能:例如,添加日志、权限验证等。
  2. 功能可以被多次组合:如 GUI 控件系统中的多种视觉效果。
  3. 避免类爆炸:避免因子类过多导致复杂的继承体系。

优缺点

优点

  1. 动态扩展对象功能,避免继承的静态绑定。
  2. 可以组合多个装饰器,灵活性高。
  3. 符合开闭原则。

缺点

  1. 需要创建大量的小类,可能会增加系统复杂性。
  2. 调试较为复杂,特别是多个装饰器嵌套时。

代码实现

需求 :以汽车为例,实现动态添加 定速巡航自动刹车车道偏离预警 三种功能。


完整代码
cpp 复制代码
#include <iostream>
#include <string>

// 抽象组件
class Car {
public:
    virtual void show() = 0; // 显示汽车配置
    virtual ~Car() = default;
};

// 具体组件:宝马
class BMW : public Car {
public:
    void show() override {
        std::cout << "This is a BMW car with basic configuration.\n";
    }
};

// 具体组件:奥迪
class Audi : public Car {
public:
    void show() override {
        std::cout << "This is an Audi car with basic configuration.\n";
    }
};

// 具体组件:奔驰
class Benz : public Car {
public:
    void show() override {
        std::cout << "This is a Benz car with basic configuration.\n";
    }
};

// 抽象装饰器
class CarDecorator : public Car {
protected:
    Car* car; // 持有被装饰的对象
public:
    CarDecorator(Car* c) : car(c) {}
    void show() override {
        car->show(); // 调用被装饰对象的 show 方法
    }
    virtual ~CarDecorator() {
        delete car;
    }
};

// 具体装饰器 1:定速巡航
class CruiseControl : public CarDecorator {
public:
    CruiseControl(Car* c) : CarDecorator(c) {}
    void show() override {
        CarDecorator::show();
        std::cout << " + Added feature: Cruise Control.\n";
    }
};

// 具体装饰器 2:自动刹车
class AutomaticBraking : public CarDecorator {
public:
    AutomaticBraking(Car* c) : CarDecorator(c) {}
    void show() override {
        CarDecorator::show();
        std::cout << " + Added feature: Automatic Braking.\n";
    }
};

// 具体装饰器 3:车道偏离预警
class LaneDepartureWarning : public CarDecorator {
public:
    LaneDepartureWarning(Car* c) : CarDecorator(c) {}
    void show() override {
        CarDecorator::show();
        std::cout << " + Added feature: Lane Departure Warning.\n";
    }
};

// 主函数
int main() {
    // 创建一个基础 BMW 对象
    Car* bmw = new BMW();

    // 给 BMW 添加定速巡航功能
    bmw = new CruiseControl(bmw);

    // 再添加自动刹车功能
    bmw = new AutomaticBraking(bmw);

    // 最后添加车道偏离预警功能
    bmw = new LaneDepartureWarning(bmw);

    // 显示 BMW 的完整配置
    bmw->show();

    // 释放内存
    delete bmw;

    return 0;
}

输出结果
复制代码
This is a BMW car with basic configuration.
 + Added feature: Cruise Control.
 + Added feature: Automatic Braking.
 + Added feature: Lane Departure Warning.

代码解析
  1. 抽象组件 Car

    • 提供统一的接口,定义所有汽车共有的功能。
  2. 具体组件

    • 例如 BMWAudiBenz,实现基本功能。
  3. 抽象装饰器 CarDecorator

    • 持有一个 Car 指针,用于动态装饰功能。
  4. 具体装饰器

    • 每个具体装饰器类实现独特的功能,如 CruiseControlAutomaticBraking
  5. 动态组合

    • 将多个装饰器嵌套在一起,实现功能的动态组合。

总结
  1. 装饰器模式使得对象功能扩展变得灵活,避免了继承的复杂性。
  2. 通过组合的方式,可以动态添加功能,减少子类数量,降低维护成本。
  3. 在实际开发中,装饰器模式非常适合需要动态扩展功能的场景,如 GUI 开发、日志记录、权限验证等。
相关推荐
至此流年莫相忘30 分钟前
设计模式:策略模式
设计模式·策略模式
MChine慕青40 分钟前
顺序表与单链表:核心原理与实战应用
linux·c语言·开发语言·数据结构·c++·算法·链表
ytadpole2 小时前
揭秘设计模式:命令模式-告别混乱,打造优雅可扩展的代码
java·设计模式
骄傲的心别枯萎2 小时前
RV1126 NO.16:通过多线程同时获取H264和H265码流
linux·c++·音视频·rv1126
落羽的落羽3 小时前
【C++】特别的程序错误处理方式——异常机制
开发语言·c++
空山新雨(大队长)3 小时前
C 语言第一课:hello word c
c++·c·exe
春蕾夏荷_7282977253 小时前
c++ 第三方库与个人封装库
c++·三方库
牵牛老人3 小时前
Qt C++ 复杂界面处理:巧用覆盖层突破复杂界面处理难题之一
数据库·c++·qt
离越词4 小时前
C++day8作业
开发语言·c++·windows
MMjeaty4 小时前
deque容器
c++