装饰者模式是一种结构性设计模式,它允许通过将对象嵌入到特殊的封装对象中来动态地为对象添加新功能。装饰者模式提供了比继承更灵活的扩展方式。
特点
1、动态添加功能:可以在运行时向对象添加新功能,而不影响其他对象。
2、透明性:装饰者与被装饰对象实现相同的接口,因此客户端可以以一致的方式使用它们。
3、组合性:可以通过多个装饰者组合使用,形成不同的功能组合。
适用场景
1、当需要动态地添加功能到对象时。
2、当希望以透明的方式为对象增加额外的职责,而不是通过子类化。
3、当希望通过组合的方式扩展对象的功能。
示例
假设我们有一个简单的文本输出系统,我们希望在文本输出时可以添加不同的装饰,比如加粗、斜体或下划线。
//g++ -o test main.cpp
#include <iostream>
#include <string>
// 抽象组件接口
class Text {
public:
virtual std::string getText() = 0;
virtual ~Text() = default;
};
// 具体组件
class PlainText : public Text {
private:
std::string text;
public:
PlainText(const std::string& text) : text(text) {}
std::string getText() override {
return text;
}
};
// 抽象装饰者
class TextDecorator : public Text {
protected:
Text* wrappedText;
public:
TextDecorator(Text* text) : wrappedText(text) {}
virtual ~TextDecorator() { delete wrappedText; }
};
// 具体装饰者:加粗
class BoldText : public TextDecorator {
public:
BoldText(Text* text) : TextDecorator(text) {}
std::string getText() override {
return "<b>" + wrappedText->getText() + "</b>";
}
};
// 具体装饰者:斜体
class ItalicText : public TextDecorator {
public:
ItalicText(Text* text) : TextDecorator(text) {}
std::string getText() override {
return "<i>" + wrappedText->getText() + "</i>";
}
};
// 具体装饰者:下划线
class UnderlineText : public TextDecorator {
public:
UnderlineText(Text* text) : TextDecorator(text) {}
std::string getText() override {
return "<u>" + wrappedText->getText() + "</u>";
}
};
int main() {
Text* myText = new PlainText("Hello, World!");
// 动态添加装饰
myText = new BoldText(myText); // 添加加粗
myText = new ItalicText(myText); // 添加斜体
myText = new UnderlineText(myText); // 添加下划线
std::cout << myText->getText() << std::endl; // 输出结果:<u><i><b>Hello, World!</b></i></u>
delete myText; // 释放内存
return 0;
}
关键点
组件接口:Text 是所有文本类型的接口,提供了 getText 方法。
具体组件:PlainText 是一个普通文本。
装饰者:TextDecorator 是抽象装饰者,BoldText、ItalicText 和 UnderlineText 是具体装饰者,可以动态地为文本添加新功能。
装饰者模式提供了一种灵活的方法来扩展对象的功能,而无需修改原始对象或使用大量的子类。