装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地将行为附加到单个对象上,而不会影响同一类的其他对象。装饰者模式为解决对象功能扩展提供了一种灵活的替代继承的方法。
核心思想
装饰者模式的核心思想是创建一系列装饰器类,作为一个与要扩展的对象共享相同接口的中间层。在不改变类的情况下,通过动态地将这些装饰器组合起来,可以为对象添加新的功能。
组成部分
-
组件接口(Component):
- 定义对象的基本行为接口,可以是抽象类或接口。
-
具体组件(ConcreteComponent):
- 实现
Component接口的基本对象,是我们计划增强功能的对象。
- 实现
-
装饰器(Decorator):
- 持有一个
Component对象的引用,并定义一个与Component接口一致的接口。它可在保持接口不变的情况下扩展对象的功能。
- 持有一个
-
具体装饰器(ConcreteDecorator):
- 继承自装饰器类,为组件添加新的功能或行为。
示例
以下是 C++ 中的一个简单的装饰者模式示例,模拟一个基本的咖啡点餐系统:
#include <iostream>
#include <memory>
// 组件接口
class Coffee {
public:
virtual ~Coffee() = default;
virtual double cost() const = 0;
virtual std::string description() const = 0;
};
// 具体组件
class SimpleCoffee : public Coffee {
public:
double cost() const override {
return 2.0;
}
std::string description() const override {
return "Simple coffee";
}
};
// 装饰器
class CoffeeDecorator : public Coffee {
public:
explicit CoffeeDecorator(std::unique_ptr<Coffee> coffee)
: coffee_(std::move(coffee)) {}
double cost() const override {
return coffee_->cost();
}
std::string description() const override {
return coffee_->description();
}
protected:
std::unique_ptr<Coffee> coffee_;
};
// 具体装饰器:添加牛奶
class MilkDecorator : public CoffeeDecorator {
public:
using CoffeeDecorator::CoffeeDecorator;
double cost() const override {
return coffee_->cost() + 0.5;
}
std::string description() const override {
return coffee_->description() + ", milk";
}
};
// 具体装饰器:添加糖
class SugarDecorator : public CoffeeDecorator {
public:
using CoffeeDecorator::CoffeeDecorator;
double cost() const override {
return coffee_->cost() + 0.2;
}
std::string description() const override {
return coffee_->description() + ", sugar";
}
};
int main() {
std::unique_ptr<Coffee> myCoffee = std::make_unique<SimpleCoffee>();
std::cout << myCoffee->description() << " costs $" << myCoffee->cost() << std::endl;
myCoffee = std::make_unique<MilkDecorator>(std::move(myCoffee));
std::cout << myCoffee->description() << " costs $" << myCoffee->cost() << std::endl;
myCoffee = std::make_unique<SugarDecorator>(std::move(myCoffee));
std::cout << myCoffee->description() << " costs $" << myCoffee->cost() << std::endl;
return 0;
}
特点和优点
-
增强功能而不改变接口:
- 装饰者模式允许增加功能而不改变现有类文件和已有的对象结构。
-
更灵活的继承替代方案:
- 通过组合而不是继承,可以在运行时通过动态地扩展和合并各个装饰器实现弹性功能。
-
遵循开闭原则:
- 可以扩展系统功能而不修改现有代码。
使用场景
-
扩展类的功能:
- 需要在不改变对象的情况下扩展和增强对象的功能,特别是当不能利用继承的情况下。
-
动态或透明的功能:
- 在特定使用场景需要对对象进行透明而灵活的功能约束。
-
独立的扩展行为:
- 需要从不同种类的行为和不同组合中构建最终对象时,装饰者模式提供灵活的配置对象的方法。
装饰者模式对需要频繁调整和组合对象功能的软件开发尤其有益,通过这种方式,功能可以在运行时灵活追加、删除,而不需要修改原有系统代码。
1456

被折叠的 条评论
为什么被折叠?



