设计模式四:装饰模式(Decorator Pattern)

发布于:2025-07-18 ⋅ 阅读:(19) ⋅ 点赞:(0)

装饰模式是一种结构型设计模式,它允许你动态地给一个对象添加额外的职责,相比继承更加灵活。

1. 模式定义

装饰模式:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。

2. 模式结构

主要角色:

  • Component(抽象构件):定义对象的接口,可以给这些对象动态添加职责

  • ConcreteComponent(具体构件):定义具体的对象,可以给它添加职责

  • Decorator(抽象装饰类):继承/实现Component,并包含一个Component的引用

  • ConcreteDecorator(具体装饰类):向构件添加具体职责

代码: 

#include <iostream>
#include <string>

// 抽象构件
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 CondimentDecorator : public Beverage {
protected:
    Beverage* beverage;
public:
    explicit CondimentDecorator(Beverage* beverage) : beverage(beverage) {}
    virtual ~CondimentDecorator() { delete beverage; }
    
    std::string getDescription() const override = 0;
};

// 具体装饰类A
class Milk : public CondimentDecorator {
public:
    explicit Milk(Beverage* beverage) : CondimentDecorator(beverage) {}
    
    std::string getDescription() const override {
        return beverage->getDescription() + ", Milk";
    }
    
    double cost() const override {
        return beverage->cost() + 0.20;
    }
};

// 具体装饰类B
class Mocha : public CondimentDecorator {
public:
    explicit Mocha(Beverage* beverage) : CondimentDecorator(beverage) {}
    
    std::string getDescription() const override {
        return beverage->getDescription() + ", Mocha";
    }
    
    double cost() const override {
        return beverage->cost() + 0.30;
    }
};

// 使用示例
int main() {
    // 创建基础饮料
    Beverage* beverage = new Espresso();
    std::cout << beverage->getDescription() << " $" << beverage->cost() << std::endl;
    
    // 用装饰类包装
    Beverage* beverage2 = new Milk(beverage);
    beverage2 = new Mocha(beverage2);  // 再次装饰
    
    std::cout << beverage2->getDescription() << " $" << beverage2->cost() << std::endl;
    
    delete beverage2;  // 会递归删除所有装饰对象
    
    return 0;
}

 uml结构

 

3. 模式特点

优点:

  1. 比继承更灵活:动态添加或撤销功能

  2. 避免子类膨胀:通过组合而非继承扩展功能

  3. 符合开闭原则:对扩展开放,对修改关闭

缺点:

  1. 会产生许多小对象:增加系统复杂度

  2. 多层装饰时调试困难:需要逐层检查

4. 应用场景

  1. 扩展单个对象的功能,而不影响其他对象

  2. 动态透明地添加职责,可以随时撤销

  3. 不适合用子类扩展的情况(如子类数量爆炸)

5. 装饰模式 vs 继承

特性 装饰模式 继承
扩展方式 动态组合 静态编译时确定
灵活性 高,可运行时调整 低,编译时固定
对象关系 组合关系 父子关系
类数量 装饰类数量较少 可能导致子类爆炸

 装饰模式是扩展对象功能的一种灵活方式,特别适合在运行时动态添加或修改对象行为的场景。


网站公告

今日签到

点亮在社区的每一天
去签到