装饰器模式 (Decorator Pattern)

装饰器模式 (Decorator Pattern)

意图:动态地给对象添加额外的职责,比继承更灵活。

基础组件
  • Component (组件):定义对象的接口
  • ConcreteComponent (具体组件):实现Component的基本功能
  • Decorator (装饰器):持有Component引用,实现Component接口
  • ConcreteDecorator (具体装饰器):添加具体功能
继承/实现关系
Component <|-- ConcreteComponent
Component <|-- Decorator
Decorator <|-- ConcreteDecorator
Decorator --> Component (组合)
应用场景
  • 需要动态添加/撤销功能
  • 不能使用子类扩展功能的情况
  • 需要多种功能组合
C++ 实现(咖啡加料场景)
#include <iostream>
#include <memory>
#include <string>

/*
* 装饰器模式
* 意图:动态地给对象添加额外的职责,比继承更灵活。
* 基础组件:
* - Component (组件):定义对象的接口
* - ConcreteComponent (具体组件):实现组件接口
* - Decorator (装饰器):持有Component引用,实现Component接口
* - ConcreteDecorator (具体装饰器):扩展Decorator,添加额外的职责
* 继承/实现关系:
* ConcreteComponent 继承自 Component
* Decorator 继承自 Component,并持有 Component 的引用
* ConcreteDecorator 继承自 Decorator,并扩展其功能
* 
* 值得注意的是,无论是基础组件还是装饰器,都实现了相同的接口,因此装饰器不仅可以使用在组件上,也可以为一个装饰器添加另一个装饰器,这样就可以动态地组合不同的装饰器来创建新的功能。
*/

// 组件:咖啡
class Coffee {
public:
    virtual ~Coffee() = default;
    virtual std::string getDescription() const = 0;
    virtual double cost() const = 0;
};

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

// 装饰器基类,它继承自 Coffee(保证对外的接口不变),并持有一个 Coffee 对象的引用(用来实现对外接口,实际是对Coffee具体实例的装饰)
class CoffeeDecorator : public Coffee {
public:
    explicit CoffeeDecorator(std::unique_ptr<Coffee> coffee)
        : coffee_(std::move(coffee)) {}

    std::string getDescription() const override {
        return coffee_->getDescription();
    }

    double cost() const override {
        return coffee_->cost();
    }

protected:
    std::unique_ptr<Coffee> coffee_;
};

// 具体装饰器:牛奶
class Milk : public CoffeeDecorator {
public:
    using CoffeeDecorator::CoffeeDecorator;

    std::string getDescription() const override {
        return coffee_->getDescription() + ", Milk";
    }

    double cost() const override {
        return coffee_->cost() + 0.50;
    }
};

// 具体装饰器:摩卡
class Mocha : public CoffeeDecorator {
public:
    using CoffeeDecorator::CoffeeDecorator;

    std::string getDescription() const override {
        return coffee_->getDescription() + ", Mocha";
    }

    double cost() const override {
        return coffee_->cost() + 0.70;
    }
};

// 具体装饰器:奶泡
class Whip : public CoffeeDecorator {
public:
    using CoffeeDecorator::CoffeeDecorator;

    std::string getDescription() const override {
        return coffee_->getDescription() + ", Whip";
    }

    double cost() const override {
        return coffee_->cost() + 0.40;
    }
};


void DecoratorPattern()
{
	std::cout << std::string(13, '-') << " Decorator Pattern " << std::string(13, '-') << "\n";

    // 基础咖啡
    auto coffee = std::make_unique<Espresso>();
    std::cout << coffee->getDescription() << ": $" << coffee->cost() << "\n";

    // 加牛奶和摩卡
    auto decoratedCoffee = std::make_unique<Mocha>(
        std::make_unique<Milk>(std::move(coffee))
    );
    std::cout << decoratedCoffee->getDescription() << ": $"
        << decoratedCoffee->cost() << "\n";

    // 再加奶泡
    auto superCoffee = std::make_unique<Whip>(std::move(decoratedCoffee));
    std::cout << superCoffee->getDescription() << ": $"
        << superCoffee->cost() << "\n";
}
组件对应关系
  • Coffee → 组件接口
  • Espresso → 具体组件
  • CoffeeDecorator → 装饰器基类
  • Milk/Mocha/Whip → 具体装饰器
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值