装饰器模式(Decorator Pattern) 是结构型设计模式中的功能扩展大师,它允许在不修改现有对象结构的情况下动态地添加新功能。本文将深入探索装饰器模式的核心思想、实现技巧以及在C++中的高效实践,解决对象功能扩展的灵活性问题。
在软件开发中,我们经常面临功能扩展的需求:
为GUI控件添加边框、阴影等视觉效果
为数据流添加加密、压缩等处理功能
为网络请求添加日志、缓存等辅助功能
为基本服务添加监控、验证等增强特性
传统扩展方式的问题:
继承导致的类爆炸:每个功能组合都需要一个子类
违反开闭原则:修改现有类来添加新功能
灵活性不足:功能组合在编译时固定
核心类臃肿:基本类包含所有可能的特性
装饰器模式通过动态包装对象解决了这些问题,提供了灵活的功能扩展方案。
[组件接口] ← [具体组件]
↑
[装饰器基类] ← [具体装饰器]
组件(Component)
定义对象的核心功能接口
具体组件(Concrete Component)
实现组件的核心功能
装饰器(Decorator)
持有组件引用
实现组件接口
具体装饰器(Concrete Decorator)
添加额外功能
让我们实现一个咖啡订单系统,展示装饰器模式的实际应用:
#include
#include
#include
#include
// ================= 组件接口:咖啡 =================
class Coffee {
public:
virtual ~Coffee() = default;
virtual std::string getDescription() const = 0;
virtual double cost() const = 0;
virtual void prepare() const {
std::cout << "准备咖啡: " << getDescription() << "\n";
}
};
// ================= 具体组件:基本咖啡 =================
class SimpleCoffee : public Coffee {
public:
std::string getDescription() const override {
return "基本咖啡";
}
double cost() const override {
return 1.99;
}
};
class Espresso : public Coffee {
public:
std::string getDescription() const override {
return "浓缩咖啡";
}
double cost() const override {
return 2.49;
}
};
// ================= 装饰器基类 =================
class CoffeeDecorator : public Coffee {
public:
explicit CoffeeDecorator(std::unique_ptr coffee)
: coffee_(std::move(coffee)) {}
std::string getDescription() const override {
return coffee_->getDescription();
}
double cost() const override {
return coffee_->cost();
}
void prepare() const override {
coffee_->prepare();
}
protected:
std::unique_ptr coffee_;
};
// ================= 具体装饰器:牛奶 =================
class MilkDecorator : public CoffeeDecorator {
public:
explicit MilkDecorator(std::unique_ptr coffee)
: CoffeeDecorator(std::move(coffee)) {}
std::string getDescription() const override {
return coffee_->getDescription() + " + 牛奶";
}
double cost() const override {
return coffee_->cost() + 0.49;
}
void prepare() const override {
CoffeeDecorator::prepare();
std::cout << " 添加新鲜牛奶\n";
}
};
// ================= 具体装饰器:糖浆 =================
class SyrupDecorator : public CoffeeDecorator {
public:
SyrupDecorator(std::unique_ptr coffee, std::string flavor)
: CoffeeDecorator(std::move(coffee)), flavor_(std::move(flavor)) {}
std::string getDescription() const override {
return coffee_->getDescription() + " + " + flavor_ + "糖浆";
}
double cost() const override {
return coffee_->cost() + 0.39;
}
void prepare() const override {
CoffeeDecorator::prepare();
std::cout << " 添加" << flavor_ << "糖浆\n";
}
private:
std::string flavor_;
};
// ================= 具体装饰器:奶油 =================
class WhipCreamDecorator : public CoffeeDecorator {
public:
explicit WhipCreamDecorator(std::unique_ptr coffee)
: CoffeeDecorator(std::move(coffee)) {}
std::string getDescription() const override {
return coffee_->getDescription() + " + 奶油";
}
double cost() const override {
return coffee_->cost() + 0.59;
}
void prepare() const override {
CoffeeDecorator::prepare();
std::cout << " 添加鲜奶油\n";
}
};
// ================= 具体装饰器:巧克力 =================
class ChocolateDecorator : public CoffeeDecorator {
public:
explicit ChocolateDecorator(std::unique_ptr coffee)
: CoffeeDecorator(std::move(coffee)) {}
std::string getDescription() const override {
return coffee_->getDescription() + " + 巧克力";
}
double cost() const override {
return coffee_->cost() + 0.69;
}
void prepare() const override {
CoffeeDecorator::prepare();
std::cout << " 撒上巧克力碎\n";
}
};
// ================= 具体装饰器:冰 =================
class IceDecorator : public CoffeeDecorator {
public:
explicit IceDecorator(std::unique_ptr coffee)
: CoffeeDecorator(std::move(coffee)) {}
std::string getDescription() const override {
return coffee_->getDescription() + " + 冰";
}
double cost() const override {
return coffee_->cost() + 0.29;
}
void prepare() const override {
CoffeeDecorator::prepare();
std::cout << " 加入冰块\n";
}
};
// ================= 客户端代码 =================
void printCoffee(const Coffee& coffee) {
std::cout << "\n================================\n";
std::cout << "订单: " << coffee.getDescription() << "\n";
coffee.prepare();
std::cout << "价格: $" << std::fixed << std::setprecision(2) << coffee.cost() << "\n";
std::cout << "================================\n";
}
int main() {
// 基本咖啡
auto simple = std::make_unique();
printCoffee(*simple);
// 浓缩咖啡加双倍牛奶
auto doubleMilkEspresso = std::make_unique(
std::make_unique(
std::make_unique()
)
);
printCoffee(*doubleMilkEspresso);
// 香草拿铁:浓缩+牛奶+香草糖浆+奶油
auto vanillaLatte = std::make_unique(
std::make_unique(
std::make_unique(
std::make_unique()
), "香草"
)
);
printCoffee(*vanillaLatte);
// 摩卡:浓缩+牛奶+巧克力
auto mocha = std::make_unique(
std::make_unique(
std::make_unique()
)
);
printCoffee(*mocha);
// 冰焦糖玛奇朵:浓缩+牛奶+焦糖糖浆+冰
auto icedCaramelMacchiato = std::make_unique(
std::make_unique(
std::make_unique(
std::make_unique()
), "焦糖"
)
);
printCoffee(*icedCaramelMacchiato);
// 豪华咖啡:浓缩+双倍巧克力+奶油+香草糖浆+焦糖糖浆
auto deluxeCoffee = std::make_unique(
std::make_unique(
std::make_unique(
std::make_unique(
std::make_unique(
std::make_unique()
)
)
), "香草"
), "焦糖"
);
printCoffee(*deluxeCoffee);
return 0;
}
// 运行时添加功能
Coffee* coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee); // 添加牛奶
coffee = new ChocolateDecorator(coffee); // 添加巧克力
传统继承:
SimpleCoffee
CoffeeWithMilk
CoffeeWithChocolate
CoffeeWithMilkAndChocolate
...
装饰器模式:
SimpleCoffee
MilkDecorator
ChocolateDecorator
任意组合
// 每个装饰器只负责一个功能
class MilkDecorator : public CoffeeDecorator { /* 只处理牛奶 */ };
class ChocolateDecorator : public CoffeeDecorator { /* 只处理巧克力 */ };
// 新增功能无需修改现有代码
class NewDecorator : public CoffeeDecorator { /* 新增装饰器 */ };
// 多层装饰器嵌套
auto coffee = std::make_unique(
std::make_unique(
std::make_unique(
std::make_unique()
)
)
);
class RemovableDecorator : public CoffeeDecorator {
public:
// 移除装饰器,返回原始咖啡
std::unique_ptr remove() {
return std::move(coffee_);
}
};
// 使用
auto coffee = std::make_unique(std::make_unique());
if (auto removable = dynamic_cast(coffee.get())) {
coffee = removable->remove(); // 移除牛奶
}
class ConditionalDecorator : public CoffeeDecorator {
public:
ConditionalDecorator(std::unique_ptr coffee, bool condition)
: CoffeeDecorator(std::move(coffee)), condition_(condition) {}
std::string getDescription() const override {
return condition_ ?
coffee_->getDescription() + " + 特殊配料" :
coffee_->getDescription();
}
double cost() const override {
return condition_ ? coffee_->cost() + 0.99 : coffee_->cost();
}
private:
bool condition_;
};
// 根据条件添加装饰
auto coffee = std::make_unique();
if (isSpecialOrder) {
coffee = std::make_unique(std::move(coffee), true);
}
// 数据处理器接口
class DataProcessor {
public:
virtual std::vector process(const std::vector& data) = 0;
};
// 基础处理器
class BaseProcessor : public DataProcessor {
std::vector process(const std::vector& data) override {
return data; // 不做处理
}
};
// 加密装饰器
class EncryptionDecorator : public DataProcessor {
public:
EncryptionDecorator(std::unique_ptr processor, std::string key)
: processor_(std::move(processor)), key_(std::move(key)) {}
std::vector process(const std::vector& data) override {
auto processed = processor_->process(data);
return encrypt(processed, key_);
}
};
// 压缩装饰器
class CompressionDecorator : public DataProcessor {
std::vector process(const std::vector& data) override {
auto processed = processor_->process(data);
return compress(processed);
}
};
// 创建处理流水线
auto processor = std::make_unique(
std::make_unique(
std::make_unique()
), "secret-key"
);
auto result = processor->process(data);
// 请求处理器接口
class RequestHandler {
public:
virtual Response handle(Request request) = 0;
};
// 基础处理器
class BasicHandler : public RequestHandler {
Response handle(Request request) override {
// 基础处理逻辑
}
};
// 日志装饰器
class LoggingDecorator : public RequestHandler {
Response handle(Request request) override {
logRequest(request);
auto response = handler_->handle(request);
logResponse(response);
return response;
}
};
// 缓存装饰器
class CacheDecorator : public RequestHandler {
Response handle(Request request) override {
if (auto cached = getFromCache(request)) {
return cached;
}
auto response = handler_->handle(request);
addToCache(request, response);
return response;
}
};
// 认证装饰器
class AuthDecorator : public RequestHandler {
Response handle(Request request) override {
if (!authenticate(request)) {
return Response(401, "Unauthorized");
}
return handler_->handle(request);
}
};
// 组合处理器
auto handler = std::make_unique(
std::make_unique(
std::make_unique(
std::make_unique()
)
)
);
// 角色接口
class Character {
public:
virtual int getAttack() const = 0;
virtual int getDefense() const = 0;
virtual std::string getDescription() const = 0;
};
// 基础角色
class Warrior : public Character {
int getAttack() const override { return 10; }
int getDefense() const override { return 5; }
std::string getDescription() const override { return "战士"; }
};
// 装备装饰器
class EquipmentDecorator : public Character {
public:
explicit EquipmentDecorator(std::unique_ptr character)
: character_(std::move(character)) {}
int getAttack() const override { return character_->getAttack(); }
int getDefense() const override { return character_->getDefense(); }
std::string getDescription() const override { return character_->getDescription(); }
protected:
std::unique_ptr character_;
};
// 武器装饰器
class SwordDecorator : public EquipmentDecorator {
int getAttack() const override { return character_->getAttack() + 8; }
int getDefense() const override { return character_->getDefense() + 2; }
std::string getDescription() const override {
return character_->getDescription() + " + 长剑";
}
};
// 盔甲装饰器
class ArmorDecorator : public EquipmentDecorator {
int getAttack() const override { return character_->getAttack() + 1; }
int getDefense() const override { return character_->getDefense() + 10; }
std::string getDescription() const override {
return character_->getDescription() + " + 板甲";
}
};
// 盾牌装饰器
class ShieldDecorator : public EquipmentDecorator {
int getAttack() const override { return character_->getAttack() + 2; }
int getDefense() const override { return character_->getDefense() + 7; }
std::string getDescription() const override {
return character_->getDescription() + " + 盾牌";
}
};
// 创建装备角色
auto character = std::make_unique(
std::make_unique(
std::make_unique(
std::make_unique()
)
)
);
std::cout << "角色: " << character->getDescription() << "\n";
std::cout << "攻击: " << character->getAttack() << "\n";
std::cout << "防御: " << character->getDefense() << "\n";
动态扩展功能
// 运行时添加功能
Coffee* coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee); // 动态添加牛奶
coffee = new ChocolateDecorator(coffee); // 动态添加巧克力
避免子类爆炸
传统继承:
SimpleCoffee
CoffeeWithMilk
CoffeeWithChocolate
CoffeeWithMilkAndChocolate
...
装饰器模式:
SimpleCoffee
MilkDecorator
ChocolateDecorator
任意组合
单一职责原则
// 每个装饰器只负责一个功能
class MilkDecorator { /* 只处理牛奶 */ };
class SugarDecorator { /* 只处理糖 */ };
开闭原则
// 新增功能无需修改现有代码
class NewToppingDecorator : public CoffeeDecorator { /* 新增装饰器 */ };
灵活组合功能
// 任意顺序组合装饰器
auto coffee1 = new MilkDecorator(new SugarDecorator(new SimpleCoffee()));
auto coffee2 = new SugarDecorator(new MilkDecorator(new SimpleCoffee()));
std::unique_ptr coffee = std::make_unique();
coffee = std::make_unique(std::move(coffee));
coffee = std::make_unique(std::move(coffee));
// 装饰器应只添加少量功能
class LightDecorator : public CoffeeDecorator {
public:
// 只添加简单功能
};
// 监控装饰器数量
const int MAX_DECORATORS = 5;
void decorate(Coffee& coffee) {
int count = 0;
Coffee* current = &coffee;
while (dynamic_cast(current)) {
if (++count > MAX_DECORATORS) {
throw std::runtime_error("过度装饰");
}
current = &static_cast(current)->getComponent();
}
}
// 清晰表达装饰功能
class BorderDecorator // 添加边框
class EncryptionDecorator // 添加加密
class LoggingDecorator // 添加日志
class CachingDecorator // 添加缓存
模式 | 关系 | 区别 |
---|---|---|
适配器模式 | 都使用包装 | 适配器改变接口,装饰器增强功能 |
组合模式 | 都使用递归组合 | 组合处理整体-部分,装饰器添加功能 |
代理模式 | 都使用包装 | 代理控制访问,装饰器添加功能 |
策略模式 | 都改变行为 | 策略替换算法,装饰器添加功能 |
组合使用示例:
// 装饰器 + 工厂模式
class CoffeeFactory {
public:
static std::unique_ptr createCoffee(const std::string& type) {
if (type == "latte") {
return std::make_unique(std::make_unique());
}
if (type == "mocha") {
return std::make_unique(
std::make_unique(std::make_unique())
);
}
// ...
}
};
class VisualComponent {
public:
virtual void draw() = 0;
};
class TextView : public VisualComponent {
void draw() override { /* 绘制文本 */ }
};
class Decorator : public VisualComponent {
public:
explicit Decorator(std::unique_ptr component)
: component_(std::move(component)) {}
void draw() override {
component_->draw();
}
protected:
std::unique_ptr component_;
};
class BorderDecorator : public Decorator {
void draw() override {
Decorator::draw();
drawBorder();
}
};
class ScrollDecorator : public Decorator {
void draw() override {
drawScrollBar();
Decorator::draw();
}
};
// 创建带边框和滚动条的文本视图
auto component = std::make_unique(
std::make_unique(
std::make_unique()
)
);
component->draw();
class DataStream {
public:
virtual void write(const std::string& data) = 0;
virtual std::string read() = 0;
};
class FileStream : public DataStream {
void write(const std::string& data) override { /* 写入文件 */ }
std::string read() override { /* 读取文件 */ }
};
class StreamDecorator : public DataStream {
public:
explicit StreamDecorator(std::unique_ptr stream)
: stream_(std::move(stream)) {}
void write(const std::string& data) override {
stream_->write(data);
}
std::string read() override {
return stream_->read();
}
protected:
std::unique_ptr stream_;
};
class CompressionDecorator : public StreamDecorator {
void write(const std::string& data) override {
auto compressed = compress(data);
stream_->write(compressed);
}
std::string read() override {
auto data = stream_->read();
return decompress(data);
}
};
class EncryptionDecorator : public StreamDecorator {
void write(const std::string& data) override {
auto encrypted = encrypt(data);
stream_->write(encrypted);
}
std::string read() override {
auto data = stream_->read();
return decrypt(data);
}
};
// 创建压缩加密的文件流
auto stream = std::make_unique(
std::make_unique(
std::make_unique("data.bin")
)
);
class Middleware {
public:
virtual Response handle(Request request) = 0;
virtual void setNext(std::unique_ptr next) = 0;
};
class BaseMiddleware : public Middleware {
public:
void setNext(std::unique_ptr next) override {
next_ = std::move(next);
}
Response handle(Request request) override {
if (next_) {
return next_->handle(request);
}
return Response(); // 默认响应
}
protected:
std::unique_ptr next_;
};
class LoggingMiddleware : public BaseMiddleware {
Response handle(Request request) override {
log(request);
return BaseMiddleware::handle(request);
}
};
class AuthMiddleware : public BaseMiddleware {
Response handle(Request request) override {
if (!authenticate(request)) {
return Response(401, "Unauthorized");
}
return BaseMiddleware::handle(request);
}
};
class CacheMiddleware : public BaseMiddleware {
Response handle(Request request) override {
if (auto cached = getFromCache(request)) {
return cached;
}
auto response = BaseMiddleware::handle(request);
addToCache(request, response);
return response;
}
};
// 创建中间件管道
auto pipeline = std::make_unique();
pipeline->setNext(std::make_unique());
pipeline->setNext(std::make_unique());
// 处理请求
auto response = pipeline->handle(request);
挑战 | 解决方案 |
---|---|
过度装饰 | 设置装饰层数限制 |
装饰器顺序问题 | 明确装饰器顺序依赖 |
性能开销 | 避免深层嵌套装饰 |
移除装饰困难 | 实现可移除装饰器 |
顺序问题解决方案:
class OrderedDecorator : public CoffeeDecorator {
public:
// 定义装饰器优先级
virtual int getPriority() const = 0;
};
void applyDecorator(std::unique_ptr& coffee, std::unique_ptr decorator) {
if (!dynamic_cast(coffee.get()) ||
decorator->getPriority() < static_cast(coffee.get())->getPriority()) {
decorator->setComponent(std::move(coffee));
coffee = std::move(decorator);
} else {
// 插入到正确位置
}
}
装饰器模式通过包装对象提供强大的功能扩展能力:
动态扩展:运行时添加或移除功能
灵活组合:任意组合功能装饰器
单一职责:每个装饰器只关注一个功能
开闭原则:扩展功能不修改现有代码
避免继承爆炸:替代多层次继承结构
使用时机:
需要在不影响其他对象的情况下动态添加职责
不适合使用子类扩展的情况
需要灵活组合多种功能
需要透明地添加或移除功能
"装饰器模式不是简单地添加功能,而是在运行时动态包装对象的艺术。它是面向对象设计中扩展功能的优雅解决方案。" - 设计模式实践者