9 装饰(Decorator)模式

装饰模式

1.1 分类

(对象)结构型

1.2 提出问题

饮料店订单系统,饮料有多种,并且可以选择加牛奶、冰激凌、巧克力等配料。

1.3 解决方案

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。找出基本组件可选层次

1.4 实现类图

在这里插入图片描述

  1. 组件(Component)声明封装器和被封装对象的公用接口。
  2. 具体组件(Concrete Component)类是被封装对象所属的类。 它定义了基础行为,但装饰类可以改变这些行为。
  3. 基础装饰(Base Decorator)类拥有指向被封装对象的引用成员变量。装饰基类会将所有操作委派给被封装的对象。
  4. 具体装饰类(Concrete Decorators)定义了可动态添加到组件的额外行为。具体装饰类会重写装饰基类的方法,并在调用父类方法之前或之后进行额外的行为。
  5. 客户端(Client)可以使用多层装饰来封装部件,只要它能使用通用接口与所有对象互动即可。

1.5 示例代码

#include <iostream>
#include <string>

//接口:具体被包裹的类,以及装饰类
class Beverage {
public:
    virtual ~Beverage() {}
    virtual std::string Operation() const = 0;
};
//具体的被装饰者
class Americano : public Beverage {
public:
    ~Americano() {}
    std::string Operation() const {
        return "美式咖啡";
    }
};
//装饰
//基础部分(可能包括额外部分)
class Ingredient : public Beverage {
protected:
    Beverage* m_beverage;
public:
    ~Ingredient() {}
    Ingredient(Beverage* beverage):m_beverage(beverage) {}
    std::string Operation() const override {
        return m_beverage->Operation();//核心代码
    }
};
//额外部分(需要委托基类,完成基础部分)
class Whip : public Ingredient {
public:
    ~Whip() {}
    Whip(Beverage* beverage) : Ingredient(beverage) {}
    std::string Operation() const override {
        //在基类的operation之前,之后都可以增加额外的操作
        return "奶昔("+Ingredient::Operation()+")";
    }
};
class Mocha : public Ingredient {
public:
    ~Mocha() {}
    Mocha(Beverage* beverage) : Ingredient(beverage) {}
    std::string Operation() const override {
        //在基类的operation之前,之后都可以增加额外的操作
        return "摩卡(" + Ingredient::Operation() + ")";
    }
};

void ClientCode(Beverage* beverage) {
    std::cout << "执行结果:" << beverage->Operation();
}
int main()
{
    std::cout << "来一杯普通美式咖啡:\n";
    Beverage* americano = new Americano();
    ClientCode(americano);
    std::cout << "\n\n";

    std::cout << "来一杯双份摩卡+奶昔的美式咖啡:\n";
    Beverage* whip1 = new Whip(americano);
    Beverage* mocha1 = new Mocha(whip1);
    Beverage* mocha2 = new Mocha(mocha1);
    ClientCode(mocha2);
    
    delete americano;
    delete whip1;
    delete mocha1;
    delete mocha2;
}

1.6 举个栗子

使用装饰模式能够对敏感数据进行压缩和加密:
在这里插入图片描述

1.7 总结

1.7.1 优点

  1. 无需创建新子类即可扩展对象的行为。
  2. 可以在运行时添加或删除对象的功能。
  3. 可以用多个装饰封装对象来组合几种行为。
  4. 单一职责原则。将实现了许多不同行为的一个大类拆分为多个较小的类。

1.7.2 缺点

  1. 在封装器栈中删除特定封装器比较困难。
  2. 实现行为不受装饰栈顺序影响的装饰比较困难。
  3. 各层的初始化配置代码看上去可能会很糟糕。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值