C++ 装饰器模式

装饰器模式(Decorator Pattern)是一种结构型设计模式,允许在不修改对象代码的情况下,动态为对象添加新功能。通过将对象包装在装饰器类中实现,遵循开放-封闭原则(对扩展开放,对修改封闭)。

  • 适用场景
    • 动态扩展对象功能(如为咖啡加配料、为函数加日志)。
    • 需要组合多种功能。
  • 核心组件
    • 抽象组件:定义接口。
    • 具体组件:被装饰的原始对象。
    • 抽象装饰器:持有一个组件对象,扩展接口。
    • 具体装饰器:实现具体功能的扩展。

📝 C++11 实现示例

以下是一个咖啡店订单系统示例,展示如何用装饰器模式为咖啡动态添加牛奶和糖。

cpp 复制代码
#include <iostream>
#include <memory>
#include <string>

// 抽象组件:咖啡接口
class Coffee {
public:
    virtual std::string getDescription() const = 0;
    virtual double cost() const = 0;
    virtual ~Coffee() = default;
};

// 具体组件:基础咖啡
class SimpleCoffee : public Coffee {
public:
    std::string getDescription() const override { return "Simple Coffee"; }
    double cost() const override { return 1.0; }
};

// 抽象装饰器
class CoffeeDecorator : public Coffee {
protected:
    std::unique_ptr<Coffee> coffee_;
public:
    explicit CoffeeDecorator(std::unique_ptr<Coffee> coffee) : coffee_(std::move(coffee)) {}
    std::string getDescription() const override { return coffee_->getDescription(); }
    double cost() const override { return coffee_->cost(); }
};

// 具体装饰器:加牛奶
class MilkDecorator : public CoffeeDecorator {
public:
    explicit MilkDecorator(std::unique_ptr<Coffee> coffee) : CoffeeDecorator(std::move(coffee)) {}
    std::string getDescription() const override { return coffee_->getDescription() + ", Milk"; }
    double cost() const override { return coffee_->cost() + 0.5; }
};

// 具体装饰器:加糖
class SugarDecorator : public CoffeeDecorator {
public:
    explicit SugarDecorator(std::unique_ptr<Coffee> coffee) : CoffeeDecorator(std::move(coffee)) {}
    std::string getDescription() const override { return coffee_->getDescription() + ", Sugar"; }
    double cost() const override { return coffee_->cost() + 0.3; }
};

// 测试
int main() {
    auto coffee = std::make_unique<SimpleCoffee>();
    std::cout << coffee->getDescription() << ": $" << coffee->cost() << '\n';

    coffee = std::make_unique<MilkDecorator>(std::move(coffee));
    std::cout << coffee->getDescription() << ": $" << coffee->cost() << '\n';

    coffee = std::make_unique<SugarDecorator>(std::move(coffee));
    std::cout << coffee->getDescription() << ": $" << coffee->cost() << '\n';

    return 0;
}

输出

复制代码
Simple Coffee: $1
Simple Coffee, Milk: $1.5
Simple Coffee, Milk, Sugar: $1.8

🔍 代码解析

  • 接口(Coffee) :定义getDescriptioncost方法。
  • 基础对象(SimpleCoffee):实现基本咖啡功能。
  • 装饰器(CoffeeDecorator) :通过std::unique_ptr持有Coffee对象,支持递归包装。
  • 具体装饰器(MilkDecorator, SugarDecorator):扩展描述和价格。
  • C++11特性
    • std::unique_ptr:管理内存,防止泄漏。
    • std::move:优化对象传递。
    • override:确保虚函数正确重写。

✅ 优点

  • 灵活性:运行时动态添加功能。
  • 可扩展:易于新增装饰器(如加巧克力)。
  • 单一职责:每个装饰器只负责一种功能。

⚠️ 缺点

  • 多层装饰可能增加代码复杂性。
  • 可能有轻微性能开销(调用链)。

🛠️ 注意事项

  • 确保组件和装饰器接口一致。
  • 避免过度装饰,保持代码清晰。
  • C++装饰器模式基于类的组合,与Python的函数装饰器(基于闭包)不同。

🌟 其他应用场景

  • 日志系统:为函数添加日志。
  • 权限控制:为操作添加权限检查。
  • 数据流:为I/O流添加加密、压缩等功能。
相关推荐
bkspiderx2 小时前
C++设计模式之结构型模式:装饰器模式(Decorator)
c++·设计模式·装饰器模式
_OP_CHEN3 小时前
C++:(四)类和对象(中)—— 构造、析构与重载
开发语言·c++·类和对象·构造函数·析构函数·运算符重载·日期类
不搞学术柒柒3 小时前
设计模式-行为型设计模式(针对对象之间的交互)
python·设计模式·交互
Madison-No74 小时前
【C++】string类的常见接口的使用
开发语言·c++·算法
一只雄牧慕4 小时前
【C++】哈希表
开发语言·数据结构·c++·散列表
代码村新手4 小时前
C语言-操作符
开发语言·c++
老赵的博客4 小时前
c++ 之多态虚函数表
java·jvm·c++
liu****4 小时前
负载均衡式的在线OJ项目编写(四)
运维·c++·负载均衡·个人开发
@卞5 小时前
第十六届蓝桥杯软件赛C组省赛C++题解(京津冀)
c语言·c++·蓝桥杯