装饰器模式与C++实现

装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许动态地向一个对象添加额外的职责,同时又不改变其结构。这种模式通过创建装饰器类来包装原有类,提供了比继承更有弹性的替代方案。

核心角色
组件接口(Component): 定义对象接口,可以动态添加职责

具体组件(ConcreteComponent): 实现组件接口的基本对象

装饰器抽象类(Decorator): 持有组件引用并实现组件接口

具体装饰器(ConcreteDecorator): 向组件添加具体职责

使用场景
装饰者模式在以下情况下特别适用:

需要在不影响其他对象的情况下动态添加职责

需要撤销或动态修改对象的功能

通过继承扩展不切实际(如子类爆炸)

需要为对象添加大量可选功能

典型应用案例
GUI组件装饰(如添加滚动条、边框)

I/O流处理(Java的BufferedInputStream等)

日志记录增强(添加时间戳、调用链信息)

权限校验装饰(在核心逻辑外添加权限层)

游戏角色装备系统(动态添加武器/防具效果)

C++代码实现示例
示例1:文本格式化装饰器

#include <iostream>
#include <string>
#include <memory>

// 组件接口
class Text {
public:
    virtual ~Text() = default;
    virtual std::string render() const = 0;
};

// 具体组件
class PlainText : public Text {
    std::string content;
public:
    explicit PlainText(const std::string& str) : content(str) {}
    std::string render() const override { return content; }
};

// 装饰器基类
class TextDecorator : public Text {
protected:
    std::unique_ptr<Text> text;
public:
    explicit TextDecorator(std::unique_ptr<Text> t) : text(std::move(t)) {}
    std::string render() const override { return text->render(); }
};

// 具体装饰器 - 加粗
class BoldDecorator : public TextDecorator {
public:
    using TextDecorator::TextDecorator;
    std::string render() const override {
        return "<b>" + text->render() + "</b>";
    }
};

// 具体装饰器 - 斜体
class ItalicDecorator : public TextDecorator {
public:
    using TextDecorator::TextDecorator;
    std::string render() const override {
        return "<i>" + text->render() + "</i>";
    }
};

// 具体装饰器 - 下划线
class UnderlineDecorator : public TextDecorator {
public:
    using TextDecorator::TextDecorator;
    std::string render() const override {
        return "<u>" + text->render() + "</u>";
    }
};

// 客户端代码
int main() {
    auto text = std::make_unique<PlainText>("Hello, World!");
    
    // 动态添加装饰
    auto decoratedText = std::make_unique<BoldDecorator>(
        std::make_unique<ItalicDecorator>(
            std::make_unique<UnderlineDecorator>(std::move(text))
        )
    );
    
    std::cout << decoratedText->render() << std::endl;
    // 输出: <b><i><u>Hello, World!</u></i></b>
    
    return 0;
}

示例2:咖啡订单系统

#include <iostream>
#include <string>
#include <memory>

// 组件接口 - 饮料
class Beverage {
public:
    virtual ~Beverage() = default;
    virtual std::string getDescription() const = 0;
    virtual double cost() const = 0;
};

// 具体组件 - 浓缩咖啡
class Espresso : public Beverage {
public:
    std::string getDescription() const override { 
        return "Espresso"; 
    }
    double cost() const override { return 1.99; }
};

// 具体组件 - 黑咖啡
class HouseBlend : public Beverage {
public:
    std::string getDescription() const override { 
        return "House Blend Coffee"; 
    }
    double cost() const override { return 0.89; }
};

// 装饰器基类 - 调料
class CondimentDecorator : public Beverage {
protected:
    std::unique_ptr<Beverage> beverage;
public:
    explicit CondimentDecorator(std::unique_ptr<Beverage> b) 
        : beverage(std::move(b)) {}
    std::string getDescription() const override = 0;
};

// 具体装饰器 - 摩卡
class Mocha : public CondimentDecorator {
public:
    using CondimentDecorator::CondimentDecorator;
    std::string getDescription() const override {
        return beverage->getDescription() + ", Mocha";
    }
    double cost() const override {
        return beverage->cost() + 0.20;
    }
};

// 具体装饰器 - 奶泡
class Whip : public CondimentDecorator {
public:
    using CondimentDecorator::CondimentDecorator;
    std::string getDescription() const override {
        return beverage->getDescription() + ", Whip";
    }
    double cost() const override {
        return beverage->cost() + 0.10;
    }
};

// 具体装饰器 - 大豆
class Soy : public CondimentDecorator {
public:
    using CondimentDecorator::CondimentDecorator;
    std::string getDescription() const override {
        return beverage->getDescription() + ", Soy";
    }
    double cost() const override {
        return beverage->cost() + 0.15;
    }
};

// 客户端代码
int main() {
    // 点一杯双倍摩卡加奶泡的浓缩咖啡
    auto beverage = std::make_unique<Espresso>();
    beverage = std::make_unique<Mocha>(std::move(beverage));
    beverage = std::make_unique<Mocha>(std::move(beverage));
    beverage = std::make_unique<Whip>(std::move(beverage));
    
    std::cout << beverage->getDescription() 
              << " $" << beverage->cost() << std::endl;
    // 输出: Espresso, Mocha, Mocha, Whip $2.49
    
    // 点一杯加大豆和奶泡的黑咖啡
    auto beverage2 = std::make_unique<HouseBlend>();
    beverage2 = std::make_unique<Soy>(std::move(beverage2));
    beverage2 = std::make_unique<Whip>(std::move(beverage2));
    
    std::cout << beverage2->getDescription() 
              << " $" << beverage2->cost() << std::endl;
    // 输出: House Blend Coffee, Soy, Whip $1.14
    
    return 0;
}

装饰者模式的优缺点
优点
比继承更灵活:可以动态添加/删除功能

避免类爆炸:不需要为每种组合创建子类

符合开闭原则:可以扩展功能而不修改原有代码

职责单一:每个装饰类只关注特定功能

运行时配置:可以在运行时决定如何装饰对象

缺点
增加复杂性:会引入大量小类,可能使系统更难理解

多层装饰问题:过度使用会导致对象被多层包装,调试困难

初始化复杂:创建高度装饰的对象需要多步构造

与相关模式对比
模式    区别
适配器模式    改变接口,装饰者模式保持接口
组合模式    装饰者模式只有一个子组件
策略模式    改变对象核心行为,装饰者模式添加辅助功能
代理模式    控制访问,装饰者模式增强功能
装饰者模式是扩展对象功能的强大工具,特别适合需要动态、透明地添加职责的场景。通过合理使用,可以构建出高度灵活且易于维护的系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值