1. 意图
动态地给一个对象添加一些额外的功能。
2. 四种角色
抽象组件(Component)、具体组件(Concrete Component)、抽象装饰(Decorator)、具体装饰(Concrete Decorator)
3. 优点
3.1 比静态继承更灵活。
3.2 避免在层次结构高层的类有太多的特征。"即用即付",只添加需要的特征。
4. 缺点
4.1 Decorator与它的Component不一样。
一个被装饰了的组件与这个组件是有差别的,使用装饰时不能依赖对象标识。
4.2 有许多小对象,会难于学习和排错。
5. 相关模式
5.1 装饰仅改变对象的职责而不改变接口,而适配器给对象一个全新的接口。
5.2 可以将装饰视为一个退化的,仅有一个组件的组合,但它的目的不在于对象聚集。
5.3 装饰可以改变对象的外表,而策略模式可以改变对象的内核。
6. 代码示意(C++)
cpp
#pragma once
#include <iostream>
#include <string>
using namespace std;
class Component
{
protected:
string m_strName;
public:
Component(const string& strName)
{
m_strName = strName;
}
virtual void Operation() = 0;
};
class ConcreteComponent : public Component
{
public:
ConcreteComponent(const string& strName) :Component(strName)
{
}
virtual void Operation() {
cout << "我是:" << m_strName << endl;
}
};
class Decorator : public Component
{
Component* m_pComponent;
public:
Decorator(const string& strName) :Component(strName) {
m_pComponent = 0;
}
virtual void Operation() {
if (m_pComponent != 0) {
m_pComponent->Operation();
}
}
public:
void Decorate(Component* pComponent) {
m_pComponent = pComponent;
}
};
class ConcreteDecoratorA :public Decorator
{
string m_addedState;
public:
ConcreteDecoratorA(const string& strName) :Decorator(strName) {
m_addedState = ",has addedState";
}
virtual void Operation() {
Decorator::Operation();
cout << "我是:" << m_strName << m_addedState << endl;
}
};
class ConcreteDecoratorB :public Decorator
{
public:
ConcreteDecoratorB(const string& strName) :Decorator(strName) {
}
virtual void Operation() {
Decorator::Operation();
AddedBehavior();
}
private:
void AddedBehavior() {
cout << "我是:" << m_strName << ",has addedBehavior" << endl;
}
};
cpp
#include "Decorator.h"
int main()
{
Component* pOrigin = new ConcreteComponent("Original");
Decorator* pDecorator = new ConcreteDecoratorA("DecoratorA");
pDecorator->Decorate(pOrigin);
pDecorator->Operation();
delete pDecorator;
pDecorator = new ConcreteDecoratorB("DecoratorB");
pDecorator->Decorate(pOrigin);
pDecorator->Operation();
delete pDecorator;
delete pOrigin;
return 0;
}
运行结果:
6.1 装饰不是单纯的继承,它还持有被装饰者的指针,更灵活(3.1)
6.2 不同的装饰器可以添加不同的功能,也可以叠加给被装饰者(3.2)
cpp
Component* pOrigin = new ConcreteComponent("Original");
Decorator* pDecoratorA = new ConcreteDecoratorA("DecoratorA");
pDecoratorA->Decorate(pOrigin);
Decorator *pDecoratorB = new ConcreteDecoratorB("DecoratorB");
pDecoratorB->Decorate(pDecoratorA);
pDecoratorB->Operation();