往期地址:
本期主题:
讲解装饰模式
1.什么是装饰模式
装饰模式是一种结构型设计模式,可以把对象的特殊行为进行封装,从而为对象绑定新的行为模式。
2.实例
2.1 场景
例如现在开发了业务通知系统,其中有一个通知类,通知有多种模式:email、微信、电话通知等等。
随着后来的发展,需求越来越复杂,有的通知希望既能email,又能wechat通知,这样的话,组合就越来越多。
按照我们最初的设计就是不停的增加子类,这样后期代码会十分庞大,不利于维护。
因此,我们在这里引入装饰模式。
- 装饰模式实现了与封装对象的相同接口;
- 从客户端的角度来看,这些对象是一致的;
接着讲上面的例子,就是把各种通知方法放入装饰。
2.2 代码
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
class Component {
public:
virtual string Operation() const = 0;
};
class ConcreteComponent : public Component {
public:
string Operation() const override {
return "ConcreteComponent";
}
};
class Decorator : public Component {
protected:
Component *component_;
public:
Decorator(Component* component) : component_(component) {}
string Operation() const override {
return this->component_->Operation();
}
};
class ConcreteDecoratorA : public Decorator {
public:
ConcreteDecoratorA(Component *component) : Decorator(component) {}
string Operation() const override {
return "ConcreteDecoratorA(" + Decorator::Operation() + ")";
}
};
class ConcreteDecoratorB : public Decorator {
public:
ConcreteDecoratorB(Component *component) : Decorator(component) {}
string Operation() const override {
return "ConcreteDecoratorB(" + Decorator::Operation() + ")";
}
};
void ClientCode(Component *component)
{
cout << "RESULT: " << component->Operation() << endl;
}
int main(void)
{
Component *simple = new ConcreteComponent;
cout << "Clinet: got a simple component:\n";
ClientCode(simple);
cout << "\n";
Component *decorator1 = new ConcreteDecoratorA(simple);
Component *decorator2 = new ConcreteDecoratorB(decorator1);
cout << "Clinet: got a decorated component:\n";
ClientCode(decorator2);
cout << "\n";
delete simple;
delete decorator1;
delete decorator2;
return 0;
}
//输出:
Clinet: got a simple component:
RESULT: ConcreteComponent
Clinet: got a decorated component:
RESULT: ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent))
输出是用ConcreteDecoratorB、ConcreteDecoratorA装饰的 component