C++装饰模式

意图

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

适用性

  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
  • 处理那些可以撤销的职责
  • 当不能采用生成子类的方法进行扩充时。一种情况时,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况是因为类定义被隐藏,或类定义不能用于生成子类。

模式结构

  1. 抽象构件角色:给出一个抽象接口,以规范准备接收附加责任的对象
  2. 具体构件角色:定义一个将要接收附加责任的类
  3. 装饰角色:持有一个构件对象的实例,并实现一个与抽象构件接口一致的接口
  4. 具体装饰角色:负责给构件对象添加上附加的责任

示意性代码

// 抽象构件角色:饮料
class Beverage {
public:
    virtual ~Beverage() { }
    virtual double cost() = 0;
};

// 具体构件角色:奶茶
class MilkTea : public Beverage {
public:
    double cost() {
        cout << "MilkTea cost: 5.5" << endl;
        return 5.5;
    }
};

// 具体构件角色:水果茶
class FruitTea : public Beverage {
public:
    double cost() override {
        cout << "FruitTea cost: 5.6" << endl;
        return 5.6;
    }
};

// 装饰角色:配料
class ToppingDecorator : public Beverage {
public:
    ToppingDecorator(Beverage* beverage)
        : m_beverage(beverage) { }
    virtual ~ToppingDecorator() { delete m_beverage; }

    virtual double cost() = 0;


protected:   
    Beverage* m_beverage;
};

// 具体装饰角色:pudding
class Pudding : public ToppingDecorator {
public:
    Pudding(Beverage* beverage) 
        : ToppingDecorator(beverage) { }

    double cost() override {
        cout << "Adding pudding cost : " << COST << endl;
        return COST + m_beverage->cost();
    }
private:
    int COST = 5;
};

// 具体装饰角色:Boba
class Boba : public ToppingDecorator {
public:
    Boba(Beverage* beverage) 
        : ToppingDecorator(beverage) { }
    
    double cost() override {
        cout << "Adding boba cost: " 
             << COST << endl;
        return COST + m_beverage->cost();
    }

private:
    int COST = 2;
};

// 使用
int main() {
    Beverage* myTea = new MilkTea();
    myTea = new Boba(myTea); // 加一份Boba
    myTea = new Boba(myTea); // 再加一份Boba
    myTea = new Pudding(myTea); // 加一份Pudding
    double totalCost = myTea->cost();
    cout << totalCost << endl;
}

img

参考

  1. 设计模式-装饰者模式 (Decorator Pattern)-保姆级攻略,实战项目
posted @ 2022-07-29 16:06  岁月飞扬  阅读(123)  评论(0编辑  收藏  举报