二、概念
装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
装饰模式是为已有功能动态地添加更多功能的一种方式。
三、说明
角色:
(1)Component是定义一个对象,可以给这些对象动态地添加职责。
(2)ConcreteComponent是定义了一个具体的对象,也可以给这个对象增加一些职责。
(3)Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但是对于Component来说,是无需知道Decorator的存在的。
(4)至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的作用。
什么时候用:
(1)需要在内部组装完成再显示出来的情况。
(2)类似于建造者模式,但是建造者模式的要求见到的过程必须是稳定的,而装饰模式的建造过程是不稳定的。
(3)我们需要把所需的功能按正确的顺序串联起来进行控制。
在起初的设计中,当系统需要新功能的时候,是向旧的类中添加新的代码。这些新的代码通常装饰了原有类的核心职责或主要行为,在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。
装饰模式提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要修饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
优点:
(1)把类的装饰功能从类中搬移去除,这样可以简化原有的类。
(2)有效地把类的核心职责和装饰功能区分开来,而且可以去除相关类中重复的装饰逻辑。
和建造者模式的区别?
建造者模式要求建造的过程必须是稳定的,而装饰模式的建造过程是不稳定的,可以有各种各样的组合方式。
#include <string>
#include <iostream>
//ConcreteComponent即Component
class Person
{
private:
std::string name;
public:
Person() {};
Person(std::string name)
{
this->name = name;
}
virtual void Show()
{
std::cout << "装饰的" << name << std::endl;
}
};
//Decorator类(装饰类),继承了Persson类,并且弱拥有Person类
class Finery :public Person
{
protected:
Person* component; //指针
public:
void Decorator(Person* component)
{
this->component = component; //指针,指向同一地址
}
void Show()
{
if (component != NULL)
component->Show();
}
};
//下面是一系列ConcreteDecorator类
class TShirts :public Finery
{
public:
void Show()
{
std::cout << "大T恤 ";
Finery::Show();
}
};
//ConcreteDecorator类
class BigTrouser :public Finery
{
public:
void Show()
{
std::cout << "垮裤 ";
Finery::Show();
}
};
//ConcreteDecorator类
class Sneakers :public Finery
{
public:
void Show()
{
std::cout << "破球鞋 ";
Finery::Show();
}
};
//ConcreteDecorator类
class Suit :public Finery
{
public:
void Show()
{
std::cout << "西装 ";
Finery::Show();
}
};
//ConcreteDecorator类
class Tie :public Finery
{
public:
void Show()
{
std::cout << "领带 ";
Finery::Show();
}
};
//ConcreteDecorator类
class LeatherShoes :public Finery
{
public:
void Show()
{
std::cout << "皮鞋 ";
Finery::Show();
}
};
int main()
{
Person* xc = NULL;
xc = new Person("小菜");
std::cout << "第一种装扮:" << std::endl;
Sneakers* pqx = NULL;
pqx = new Sneakers();
BigTrouser* kk = NULL;
kk = new BigTrouser();
TShirts* dtx = NULL;
dtx = new TShirts();
pqx->Decorator(xc);
kk->Decorator(pqx);
dtx->Decorator(kk);
dtx->Show();
std::cout << "第二种装扮:" << std::endl;
LeatherShoes* px = NULL;
px = new LeatherShoes();
Tie* ld = NULL;
ld = new Tie();
Suit* xz = NULL;
xz = new Suit();
px->Decorator(xc);
ld->Decorator(px);
xz->Decorator(ld);
xz->Show();
if (xc != NULL)
{
delete xc;
xc = NULL;
}
if (pqx != NULL)
{
delete pqx;
pqx = NULL;
}
if (kk != NULL)
{
delete kk;
kk = NULL;
}
if (dtx != NULL)
{
delete dtx;
dtx = NULL;
}
if (px != NULL)
{
delete px;
px = NULL;
}
if (ld != NULL)
{
delete ld;
ld = NULL;
}
if (xz != NULL)
{
delete xz;
xz = NULL;
}
return 0;
}
原文参考: