装饰器模式(Decorator Pattern)
定义
装饰器模式是一种结构性设计模式,通过 动态组合对象 的方式,为对象添加额外功能,而无需修改原有类。
装饰器模式的核心思想
- 对象增强:在现有类的基础上动态添加功能,而不修改类的代码。
- 功能组合:通过多个装饰器的嵌套,可以灵活组合功能。
- 继承与组合:
- 继承是一种 静态扩展。
- 装饰器模式是一种 动态扩展。
类结构
装饰器模式的类结构包含以下几部分:
-
抽象组件(Component):
- 定义接口,声明核心功能方法。
- 所有被装饰类和装饰器类都必须实现此接口。
-
具体组件(ConcreteComponent):
- 实现抽象组件的接口,定义基本功能。
-
装饰器基类(Decorator):
- 实现抽象组件接口。
- 持有一个组件的引用(指针),并通过组合扩展功能。
-
具体装饰器类(ConcreteDecorator):
- 从装饰器基类派生。
- 对原始功能进行增强。
装饰器模式与代理模式的区别
区别点 | 装饰器模式 | 代理模式 |
---|---|---|
目的 | 增强类的功能 | 控制访问权限 |
实现的重点 | 功能扩展 | 权限控制 |
类的设计 | 装饰器类持有被装饰对象的指针 | 代理类持有被代理对象的指针 |
调用顺序 | 递归调用,逐层增强功能 | 代理类决定是否调用实际方法 |
应用场景
- 需要动态扩展功能:例如,添加日志、权限验证等。
- 功能可以被多次组合:如 GUI 控件系统中的多种视觉效果。
- 避免类爆炸:避免因子类过多导致复杂的继承体系。
优缺点
优点:
- 动态扩展对象功能,避免继承的静态绑定。
- 可以组合多个装饰器,灵活性高。
- 符合开闭原则。
缺点:
- 需要创建大量的小类,可能会增加系统复杂性。
- 调试较为复杂,特别是多个装饰器嵌套时。
代码实现
需求:以汽车为例,实现动态添加 定速巡航、自动刹车 和 车道偏离预警 三种功能。
完整代码
#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.
代码解析
-
抽象组件
Car
:- 提供统一的接口,定义所有汽车共有的功能。
-
具体组件:
- 例如
BMW
、Audi
和Benz
,实现基本功能。
- 例如
-
抽象装饰器
CarDecorator
:- 持有一个
Car
指针,用于动态装饰功能。
- 持有一个
-
具体装饰器:
- 每个具体装饰器类实现独特的功能,如
CruiseControl
、AutomaticBraking
。
- 每个具体装饰器类实现独特的功能,如
-
动态组合:
- 将多个装饰器嵌套在一起,实现功能的动态组合。
总结
- 装饰器模式使得对象功能扩展变得灵活,避免了继承的复杂性。
- 通过组合的方式,可以动态添加功能,减少子类数量,降低维护成本。
- 在实际开发中,装饰器模式非常适合需要动态扩展功能的场景,如 GUI 开发、日志记录、权限验证等。