设计模式 | 装饰器模式

装饰器模式(Decorator Pattern) 是结构型设计模式中的功能扩展大师,它允许在不修改现有对象结构的情况下动态地添加新功能。本文将深入探索装饰器模式的核心思想、实现技巧以及在C++中的高效实践,解决对象功能扩展的灵活性问题。

为什么需要装饰器模式?

在软件开发中,我们经常面临功能扩展的需求:

  • 为GUI控件添加边框、阴影等视觉效果

  • 为数据流添加加密、压缩等处理功能

  • 为网络请求添加日志、缓存等辅助功能

  • 为基本服务添加监控、验证等增强特性

传统扩展方式的问题:

  • 继承导致的类爆炸:每个功能组合都需要一个子类

  • 违反开闭原则:修改现有类来添加新功能

  • 灵活性不足:功能组合在编译时固定

  • 核心类臃肿:基本类包含所有可能的特性

装饰器模式通过动态包装对象解决了这些问题,提供了灵活的功能扩展方案。

装饰器模式的核心概念

模式结构解析

[组件接口] ← [具体组件]
      ↑
[装饰器基类] ← [具体装饰器]

关键角色定义

  1. 组件(Component)

    • 定义对象的核心功能接口

  2. 具体组件(Concrete Component)

    • 实现组件的核心功能

  3. 装饰器(Decorator)

    • 持有组件引用

    • 实现组件接口

  4. 具体装饰器(Concrete Decorator)

    • 添加额外功能

C++实现:咖啡订单系统

让我们实现一个咖啡订单系统,展示装饰器模式的实际应用:

#include 
#include 
#include 
#include 

// ================= 组件接口:咖啡 =================
class Coffee {
public:
    virtual ~Coffee() = default;
    
    virtual std::string getDescription() const = 0;
    virtual double cost() const = 0;
    
    virtual void prepare() const {
        std::cout << "准备咖啡: " << getDescription() << "\n";
    }
};

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

class Espresso : public Coffee {
public:
    std::string getDescription() const override {
        return "浓缩咖啡";
    }
    
    double cost() const override {
        return 2.49;
    }
};

// ================= 装饰器基类 =================
class CoffeeDecorator : public Coffee {
public:
    explicit CoffeeDecorator(std::unique_ptr coffee)
        : coffee_(std::move(coffee)) {}
    
    std::string getDescription() const override {
        return coffee_->getDescription();
    }
    
    double cost() const override {
        return coffee_->cost();
    }
    
    void prepare() const override {
        coffee_->prepare();
    }

protected:
    std::unique_ptr coffee_;
};

// ================= 具体装饰器:牛奶 =================
class MilkDecorator : public CoffeeDecorator {
public:
    explicit MilkDecorator(std::unique_ptr coffee)
        : CoffeeDecorator(std::move(coffee)) {}
    
    std::string getDescription() const override {
        return coffee_->getDescription() + " + 牛奶";
    }
    
    double cost() const override {
        return coffee_->cost() + 0.49;
    }
    
    void prepare() const override {
        CoffeeDecorator::prepare();
        std::cout << "  添加新鲜牛奶\n";
    }
};

// ================= 具体装饰器:糖浆 =================
class SyrupDecorator : public CoffeeDecorator {
public:
    SyrupDecorator(std::unique_ptr coffee, std::string flavor)
        : CoffeeDecorator(std::move(coffee)), flavor_(std::move(flavor)) {}
    
    std::string getDescription() const override {
        return coffee_->getDescription() + " + " + flavor_ + "糖浆";
    }
    
    double cost() const override {
        return coffee_->cost() + 0.39;
    }
    
    void prepare() const override {
        CoffeeDecorator::prepare();
        std::cout << "  添加" << flavor_ << "糖浆\n";
    }

private:
    std::string flavor_;
};

// ================= 具体装饰器:奶油 =================
class WhipCreamDecorator : public CoffeeDecorator {
public:
    explicit WhipCreamDecorator(std::unique_ptr coffee)
        : CoffeeDecorator(std::move(coffee)) {}
    
    std::string getDescription() const override {
        return coffee_->getDescription() + " + 奶油";
    }
    
    double cost() const override {
        return coffee_->cost() + 0.59;
    }
    
    void prepare() const override {
        CoffeeDecorator::prepare();
        std::cout << "  添加鲜奶油\n";
    }
};

// ================= 具体装饰器:巧克力 =================
class ChocolateDecorator : public CoffeeDecorator {
public:
    explicit ChocolateDecorator(std::unique_ptr coffee)
        : CoffeeDecorator(std::move(coffee)) {}
    
    std::string getDescription() const override {
        return coffee_->getDescription() + " + 巧克力";
    }
    
    double cost() const override {
        return coffee_->cost() + 0.69;
    }
    
    void prepare() const override {
        CoffeeDecorator::prepare();
        std::cout << "  撒上巧克力碎\n";
    }
};

// ================= 具体装饰器:冰 =================
class IceDecorator : public CoffeeDecorator {
public:
    explicit IceDecorator(std::unique_ptr coffee)
        : CoffeeDecorator(std::move(coffee)) {}
    
    std::string getDescription() const override {
        return coffee_->getDescription() + " + 冰";
    }
    
    double cost() const override {
        return coffee_->cost() + 0.29;
    }
    
    void prepare() const override {
        CoffeeDecorator::prepare();
        std::cout << "  加入冰块\n";
    }
};

// ================= 客户端代码 =================
void printCoffee(const Coffee& coffee) {
    std::cout << "\n================================\n";
    std::cout << "订单: " << coffee.getDescription() << "\n";
    coffee.prepare();
    std::cout << "价格: $" << std::fixed << std::setprecision(2) << coffee.cost() << "\n";
    std::cout << "================================\n";
}

int main() {
    // 基本咖啡
    auto simple = std::make_unique();
    printCoffee(*simple);
    
    // 浓缩咖啡加双倍牛奶
    auto doubleMilkEspresso = std::make_unique(
        std::make_unique(
            std::make_unique()
        )
    );
    printCoffee(*doubleMilkEspresso);
    
    // 香草拿铁:浓缩+牛奶+香草糖浆+奶油
    auto vanillaLatte = std::make_unique(
        std::make_unique(
            std::make_unique(
                std::make_unique()
            ), "香草"
        )
    );
    printCoffee(*vanillaLatte);
    
    // 摩卡:浓缩+牛奶+巧克力
    auto mocha = std::make_unique(
        std::make_unique(
            std::make_unique()
        )
    );
    printCoffee(*mocha);
    
    // 冰焦糖玛奇朵:浓缩+牛奶+焦糖糖浆+冰
    auto icedCaramelMacchiato = std::make_unique(
        std::make_unique(
            std::make_unique(
                std::make_unique()
            ), "焦糖"
        )
    );
    printCoffee(*icedCaramelMacchiato);
    
    // 豪华咖啡:浓缩+双倍巧克力+奶油+香草糖浆+焦糖糖浆
    auto deluxeCoffee = std::make_unique(
        std::make_unique(
            std::make_unique(
                std::make_unique(
                    std::make_unique(
                        std::make_unique()
                    )
                )
            ), "香草"
        ), "焦糖"
    );
    printCoffee(*deluxeCoffee);
    
    return 0;
}

装饰器模式的四大优势

1. 动态添加功能

// 运行时添加功能
Coffee* coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee); // 添加牛奶
coffee = new ChocolateDecorator(coffee); // 添加巧克力

2. 避免类爆炸

传统继承:
  SimpleCoffee
  CoffeeWithMilk
  CoffeeWithChocolate
  CoffeeWithMilkAndChocolate
  ...

装饰器模式:
  SimpleCoffee
  MilkDecorator
  ChocolateDecorator
  任意组合

3. 单一职责原则

// 每个装饰器只负责一个功能
class MilkDecorator : public CoffeeDecorator { /* 只处理牛奶 */ };
class ChocolateDecorator : public CoffeeDecorator { /* 只处理巧克力 */ };

4. 开闭原则

// 新增功能无需修改现有代码
class NewDecorator : public CoffeeDecorator { /* 新增装饰器 */ };

装饰器模式的高级应用

1. 多层装饰器

// 多层装饰器嵌套
auto coffee = std::make_unique(
    std::make_unique(
        std::make_unique(
            std::make_unique()
        )
    )
);

2. 装饰器移除功能

class RemovableDecorator : public CoffeeDecorator {
public:
    // 移除装饰器,返回原始咖啡
    std::unique_ptr remove() {
        return std::move(coffee_);
    }
};

// 使用
auto coffee = std::make_unique(std::make_unique());
if (auto removable = dynamic_cast(coffee.get())) {
    coffee = removable->remove(); // 移除牛奶
}

3. 条件装饰器

class ConditionalDecorator : public CoffeeDecorator {
public:
    ConditionalDecorator(std::unique_ptr coffee, bool condition)
        : CoffeeDecorator(std::move(coffee)), condition_(condition) {}
    
    std::string getDescription() const override {
        return condition_ ? 
            coffee_->getDescription() + " + 特殊配料" : 
            coffee_->getDescription();
    }
    
    double cost() const override {
        return condition_ ? coffee_->cost() + 0.99 : coffee_->cost();
    }

private:
    bool condition_;
};

// 根据条件添加装饰
auto coffee = std::make_unique();
if (isSpecialOrder) {
    coffee = std::make_unique(std::move(coffee), true);
}

装饰器模式的应用场景

1. 文件处理流水线

// 数据处理器接口
class DataProcessor {
public:
    virtual std::vector process(const std::vector& data) = 0;
};

// 基础处理器
class BaseProcessor : public DataProcessor {
    std::vector process(const std::vector& data) override {
        return data; // 不做处理
    }
};

// 加密装饰器
class EncryptionDecorator : public DataProcessor {
public:
    EncryptionDecorator(std::unique_ptr processor, std::string key)
        : processor_(std::move(processor)), key_(std::move(key)) {}
    
    std::vector process(const std::vector& data) override {
        auto processed = processor_->process(data);
        return encrypt(processed, key_);
    }
};

// 压缩装饰器
class CompressionDecorator : public DataProcessor {
    std::vector process(const std::vector& data) override {
        auto processed = processor_->process(data);
        return compress(processed);
    }
};

// 创建处理流水线
auto processor = std::make_unique(
    std::make_unique(
        std::make_unique()
    ), "secret-key"
);

auto result = processor->process(data);

2. 网络请求处理

// 请求处理器接口
class RequestHandler {
public:
    virtual Response handle(Request request) = 0;
};

// 基础处理器
class BasicHandler : public RequestHandler {
    Response handle(Request request) override {
        // 基础处理逻辑
    }
};

// 日志装饰器
class LoggingDecorator : public RequestHandler {
    Response handle(Request request) override {
        logRequest(request);
        auto response = handler_->handle(request);
        logResponse(response);
        return response;
    }
};

// 缓存装饰器
class CacheDecorator : public RequestHandler {
    Response handle(Request request) override {
        if (auto cached = getFromCache(request)) {
            return cached;
        }
        auto response = handler_->handle(request);
        addToCache(request, response);
        return response;
    }
};

// 认证装饰器
class AuthDecorator : public RequestHandler {
    Response handle(Request request) override {
        if (!authenticate(request)) {
            return Response(401, "Unauthorized");
        }
        return handler_->handle(request);
    }
};

// 组合处理器
auto handler = std::make_unique(
    std::make_unique(
        std::make_unique(
            std::make_unique()
        )
    )
);

3. 游戏角色装备系统

// 角色接口
class Character {
public:
    virtual int getAttack() const = 0;
    virtual int getDefense() const = 0;
    virtual std::string getDescription() const = 0;
};

// 基础角色
class Warrior : public Character {
    int getAttack() const override { return 10; }
    int getDefense() const override { return 5; }
    std::string getDescription() const override { return "战士"; }
};

// 装备装饰器
class EquipmentDecorator : public Character {
public:
    explicit EquipmentDecorator(std::unique_ptr character)
        : character_(std::move(character)) {}
    
    int getAttack() const override { return character_->getAttack(); }
    int getDefense() const override { return character_->getDefense(); }
    std::string getDescription() const override { return character_->getDescription(); }

protected:
    std::unique_ptr character_;
};

// 武器装饰器
class SwordDecorator : public EquipmentDecorator {
    int getAttack() const override { return character_->getAttack() + 8; }
    int getDefense() const override { return character_->getDefense() + 2; }
    std::string getDescription() const override { 
        return character_->getDescription() + " + 长剑"; 
    }
};

// 盔甲装饰器
class ArmorDecorator : public EquipmentDecorator {
    int getAttack() const override { return character_->getAttack() + 1; }
    int getDefense() const override { return character_->getDefense() + 10; }
    std::string getDescription() const override { 
        return character_->getDescription() + " + 板甲"; 
    }
};

// 盾牌装饰器
class ShieldDecorator : public EquipmentDecorator {
    int getAttack() const override { return character_->getAttack() + 2; }
    int getDefense() const override { return character_->getDefense() + 7; }
    std::string getDescription() const override { 
        return character_->getDescription() + " + 盾牌"; 
    }
};

// 创建装备角色
auto character = std::make_unique(
    std::make_unique(
        std::make_unique(
            std::make_unique()
        )
    )
);

std::cout << "角色: " << character->getDescription() << "\n";
std::cout << "攻击: " << character->getAttack() << "\n";
std::cout << "防御: " << character->getDefense() << "\n";

装饰器模式的五大优势

  1. 动态扩展功能

    // 运行时添加功能
    Coffee* coffee = new SimpleCoffee();
    coffee = new MilkDecorator(coffee); // 动态添加牛奶
    coffee = new ChocolateDecorator(coffee); // 动态添加巧克力
  2. 避免子类爆炸

    传统继承:
      SimpleCoffee
      CoffeeWithMilk
      CoffeeWithChocolate
      CoffeeWithMilkAndChocolate
      ...
    
    装饰器模式:
      SimpleCoffee
      MilkDecorator
      ChocolateDecorator
      任意组合
  3. 单一职责原则

    // 每个装饰器只负责一个功能
    class MilkDecorator { /* 只处理牛奶 */ };
    class SugarDecorator { /* 只处理糖 */ };
  4. 开闭原则

    // 新增功能无需修改现有代码
    class NewToppingDecorator : public CoffeeDecorator { /* 新增装饰器 */ };
  5. 灵活组合功能

    // 任意顺序组合装饰器
    auto coffee1 = new MilkDecorator(new SugarDecorator(new SimpleCoffee()));
    auto coffee2 = new SugarDecorator(new MilkDecorator(new SimpleCoffee()));

装饰器模式的最佳实践

1. 使用智能指针管理资源

std::unique_ptr coffee = std::make_unique();
coffee = std::make_unique(std::move(coffee));
coffee = std::make_unique(std::move(coffee));

2. 保持装饰器轻量级

// 装饰器应只添加少量功能
class LightDecorator : public CoffeeDecorator {
public:
    // 只添加简单功能
};

3. 避免过度装饰

// 监控装饰器数量
const int MAX_DECORATORS = 5;

void decorate(Coffee& coffee) {
    int count = 0;
    Coffee* current = &coffee;
    while (dynamic_cast(current)) {
        if (++count > MAX_DECORATORS) {
            throw std::runtime_error("过度装饰");
        }
        current = &static_cast(current)->getComponent();
    }
}

4. 装饰器命名规范

// 清晰表达装饰功能
class BorderDecorator      // 添加边框
class EncryptionDecorator  // 添加加密
class LoggingDecorator     // 添加日志
class CachingDecorator     // 添加缓存

装饰器模式与其他模式的关系

模式 关系 区别
适配器模式 都使用包装 适配器改变接口,装饰器增强功能
组合模式 都使用递归组合 组合处理整体-部分,装饰器添加功能
代理模式 都使用包装 代理控制访问,装饰器添加功能
策略模式 都改变行为 策略替换算法,装饰器添加功能

组合使用示例

// 装饰器 + 工厂模式
class CoffeeFactory {
public:
    static std::unique_ptr createCoffee(const std::string& type) {
        if (type == "latte") {
            return std::make_unique(std::make_unique());
        }
        if (type == "mocha") {
            return std::make_unique(
                std::make_unique(std::make_unique())
            );
        }
        // ...
    }
};

应用案例

1. GUI控件装饰

class VisualComponent {
public:
    virtual void draw() = 0;
};

class TextView : public VisualComponent {
    void draw() override { /* 绘制文本 */ }
};

class Decorator : public VisualComponent {
public:
    explicit Decorator(std::unique_ptr component)
        : component_(std::move(component)) {}
    
    void draw() override {
        component_->draw();
    }

protected:
    std::unique_ptr component_;
};

class BorderDecorator : public Decorator {
    void draw() override {
        Decorator::draw();
        drawBorder();
    }
};

class ScrollDecorator : public Decorator {
    void draw() override {
        drawScrollBar();
        Decorator::draw();
    }
};

// 创建带边框和滚动条的文本视图
auto component = std::make_unique(
    std::make_unique(
        std::make_unique()
    )
);
component->draw();

2. 流处理系统

class DataStream {
public:
    virtual void write(const std::string& data) = 0;
    virtual std::string read() = 0;
};

class FileStream : public DataStream {
    void write(const std::string& data) override { /* 写入文件 */ }
    std::string read() override { /* 读取文件 */ }
};

class StreamDecorator : public DataStream {
public:
    explicit StreamDecorator(std::unique_ptr stream)
        : stream_(std::move(stream)) {}
    
    void write(const std::string& data) override {
        stream_->write(data);
    }
    
    std::string read() override {
        return stream_->read();
    }

protected:
    std::unique_ptr stream_;
};

class CompressionDecorator : public StreamDecorator {
    void write(const std::string& data) override {
        auto compressed = compress(data);
        stream_->write(compressed);
    }
    
    std::string read() override {
        auto data = stream_->read();
        return decompress(data);
    }
};

class EncryptionDecorator : public StreamDecorator {
    void write(const std::string& data) override {
        auto encrypted = encrypt(data);
        stream_->write(encrypted);
    }
    
    std::string read() override {
        auto data = stream_->read();
        return decrypt(data);
    }
};

// 创建压缩加密的文件流
auto stream = std::make_unique(
    std::make_unique(
        std::make_unique("data.bin")
    )
);

3. 中间件管道

class Middleware {
public:
    virtual Response handle(Request request) = 0;
    virtual void setNext(std::unique_ptr next) = 0;
};

class BaseMiddleware : public Middleware {
public:
    void setNext(std::unique_ptr next) override {
        next_ = std::move(next);
    }
    
    Response handle(Request request) override {
        if (next_) {
            return next_->handle(request);
        }
        return Response(); // 默认响应
    }

protected:
    std::unique_ptr next_;
};

class LoggingMiddleware : public BaseMiddleware {
    Response handle(Request request) override {
        log(request);
        return BaseMiddleware::handle(request);
    }
};

class AuthMiddleware : public BaseMiddleware {
    Response handle(Request request) override {
        if (!authenticate(request)) {
            return Response(401, "Unauthorized");
        }
        return BaseMiddleware::handle(request);
    }
};

class CacheMiddleware : public BaseMiddleware {
    Response handle(Request request) override {
        if (auto cached = getFromCache(request)) {
            return cached;
        }
        auto response = BaseMiddleware::handle(request);
        addToCache(request, response);
        return response;
    }
};

// 创建中间件管道
auto pipeline = std::make_unique();
pipeline->setNext(std::make_unique());
pipeline->setNext(std::make_unique());

// 处理请求
auto response = pipeline->handle(request);

装饰器模式的挑战与解决方案

挑战 解决方案
过度装饰 设置装饰层数限制
装饰器顺序问题 明确装饰器顺序依赖
性能开销 避免深层嵌套装饰
移除装饰困难 实现可移除装饰器

顺序问题解决方案

class OrderedDecorator : public CoffeeDecorator {
public:
    // 定义装饰器优先级
    virtual int getPriority() const = 0;
};

void applyDecorator(std::unique_ptr& coffee, std::unique_ptr decorator) {
    if (!dynamic_cast(coffee.get()) || 
        decorator->getPriority() < static_cast(coffee.get())->getPriority()) {
        decorator->setComponent(std::move(coffee));
        coffee = std::move(decorator);
    } else {
        // 插入到正确位置
    }
}

总结

装饰器模式通过包装对象提供强大的功能扩展能力:

  1. 动态扩展:运行时添加或移除功能

  2. 灵活组合:任意组合功能装饰器

  3. 单一职责:每个装饰器只关注一个功能

  4. 开闭原则:扩展功能不修改现有代码

  5. 避免继承爆炸:替代多层次继承结构

使用时机

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

  • 不适合使用子类扩展的情况

  • 需要灵活组合多种功能

  • 需要透明地添加或移除功能

"装饰器模式不是简单地添加功能,而是在运行时动态包装对象的艺术。它是面向对象设计中扩展功能的优雅解决方案。" - 设计模式实践者

你可能感兴趣的:(设计模式 | 装饰器模式)