classDiagram
Component <.. ConcreteComponent
Component <.. Decorator
Decorator <-- ConcreteDecoratorA
Decorator <-- ConcreteDecoratorB
class Component{
<<abstract>>
+Operation() string
}
class ConcreteComponent {
+ Operation()
}
class Decorator{
- m_component:Component*
+Operation()
}
class ConcreteDecoratorA{
+ Operation()
+ AddedBehavior()
}
class ConcreteDecoratorB{
+ Operation()
+ AddedBehavior()
}
来源: 代码
#include <bits/stdc++.h>
/*
*@brief 指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
* 场景:
* 优点:
* (1)装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用;
* (2)通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果;
* (3)装饰器模式完全遵守开闭原则.
* 缺点:
* 装饰模式会增加许多子类,过度使用会增加程序得复杂性。
*/
//基础组件接口定义了可以被装饰器修改的操作
class Component
{
public:
virtual ~Component() {}
virtual std::string Operation() const = 0;
};
//具体组件提供了操作的默认实现,这些类在程序中可能会有几个变体
class ConcreteComponent : public Component
{
public:
std::string Operation() const override
{
return "ConcreteComponent";
}
};
//装饰器基类和其他组件遵循相同的接口。这个类的主要目的是为所有的具体装饰器定义封装接口。
//封装的默认实现代码中可能会包含一个保存被封装组件的成员变量,并且负责对齐进行初始化
class Decorator : public Component
{
protected:
Component *component_;
public:
Decorator(Component *component) : component_(component) {}
//装饰器会将所有的工作分派给被封装的组件
std::string Operation() const override
{
return this->component_->Operation();
}
};
//具体装饰器必须在被封装对象上调用方法,不过也可以自行在结果中添加一些内容。
class ConcreteDecoratorA : public Decorator
{
//装饰器可以调用父类的是实现,来替代直接调用组件方法。
public:
ConcreteDecoratorA(Component *component) : Decorator(component) {}
std::string Operation() const override
{
return "ConcreteDecoratorA(" + Decorator::Operation() + ")";
}
};
//装饰器可以在调用封装的组件对象的方法前后执行自己的方法
class ConcreteDecoratorB : public Decorator
{
public:
ConcreteDecoratorB(Component *component) : Decorator(component)
{
}
std::string Operation() const override
{
return "ConcreteDecoratorB(" + Decorator::Operation() + ")";
}
};
//客户端代码可以使用组件接口来操作所有的具体对象。这种方式可以使客户端和具体的实现类脱耦
void ClientCode(Component *component)
{
// ...
std::cout << "RESULT: " << component->Operation();
// ...
}
int main()
{
Component *simple = new ConcreteComponent;
std::cout << "Client: I've got a simple component:\n";
// RESULT: ConcreteComponent
ClientCode(simple);
std::cout << "\n\n";
Component *decorator1 = new ConcreteDecoratorA(simple);
// RESULT: ConcreteDecoratorA(ConcreteComponent
ClientCode(decorator1);
Component *decorator2 = new ConcreteDecoratorB(decorator1);
// RESULT: ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent))
ClientCode(decorator2);
std::cout << "\n";
delete simple;
delete decorator1;
delete decorator2;
return 0;
}