前言
参考大话设计模式;
详细内容参见大话模式一书第六章,该书使用C#实现,本实验通过C++语言实现。
装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。[DP]
一 装饰模式原理
装饰模式(Decorator)结构图
聚合(Aggregation)关系:大雁和雁群,上图中空心菱形+箭头表示聚合关系
组合(Composition)关系:大雁和翅膀 ,实心菱形+箭头表示组合(Composition)关系
在startUML工具中,聚合使用空心菱形+直线,组合是菱形+直线。
c++测试代码:
#include <iostream>
#include <stdio.h>
#include <mutex>//锁头文件
using namespace std;
class Component{
public:
virtual void Operation() = 0;
virtual ~Component(){
}
};
class ConcreteComponent:public Component
{
public:
void Operation(){
cout << "ConcreteComponent" << endl;
}
};
class Decorator:public Component{
protected:
Component *component = nullptr;
public:
void SetComponent(Component *_component){
this->component = _component;
}
void Operation(){
if(component != nullptr){
component->Operation();
}
}
};
class ConcreteDecoratorA:public Decorator
{
private:
string addedState;
public:
void Operation(){
Decorator::Operation();
addedState = "new State";
cout << "具体装饰对象A的操作" << endl;
}
};
class ConcreteDecoratorB:public Decorator
{
public:
void Operation(){
Decorator::Operation();
AddedBehavior();
cout << "具体装饰对象B的操作" << endl;
}
private:
void AddedBehavior()
{
cout << "AddedBehavior" << endl;
}
};
int main(void)
{
ConcreteComponent *c = new ConcreteComponent();
ConcreteDecoratorA *d1 = new ConcreteDecoratorA();
ConcreteDecoratorB *d2 = new ConcreteDecoratorB();
d1->SetComponent(c);
d2->SetComponent(d1);
d2->Operation();
cout << "--endl--" << endl;
return 0;
}
测试结果:
ConcreteComponent
具体装饰对象A的操作
AddedBehavior
具体装饰对象B的操作
--endl--
装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中[DPE
二 装饰模式变身
如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类
根据这段文字的描述,UML结构图变身后的形态:
三 书上的UML图
四 C++改写后的UML图和代码
大框架是没变的,只是语言由C#变成了C++;
测试代码:
#include <iostream>
#include <stdio.h>
#include <mutex>//锁头文件
using namespace std;
//“Person”类(ConcreteComponent)
class Person{
public:
Person(){
}
Person(string _name):name(_name){
}
virtual void Show(){
cout << "装扮的:" << this->name << endl;
}
private:
string name;
};
//服饰类(Decorator)
class Finery:public Person
{
public:
Person *component = nullptr;
void Decorate(Person *_component){
this->component = _component;
}
virtual void Show(){
if(component != nullptr){
component->Show();
}
}
};
class fengyi:public Finery
{
public:
virtual void Show(){
cout << "风衣" << endl;
Finery::Show();
}
};
class yundongxie:public Finery
{
public:
virtual void Show(){
cout << "运动鞋" << endl;
Finery::Show();
}
};
class mojing:public Finery
{
public:
void Show(){
cout << "墨镜" << endl;
Finery::Show();
}
};
class kouzhao:public Finery
{
public:
void Show(){
cout << "口罩" << endl;
Finery::Show();
}
};
class xifu:public Finery
{
public:
void Show(){
cout << "西服" << endl;
Finery::Show();
}
};
int main(void)
{
cout << "装扮1" << endl;
Person *p1 = new Person("lkmao");
fengyi *fy = new fengyi();
yundongxie *ydx = new yundongxie();
fy->Decorate(p1);
ydx->Decorate(fy);
ydx->Show();
cout << endl << "装扮2" << endl;
Person *p2 = new Person("laoliu");
mojing *mj = new mojing();
kouzhao *kz = new kouzhao();
xifu *xf = new xifu();
mj->Decorate(p2);
kz->Decorate(mj);
xf->Decorate(kz);
xf->Show();
cout << "--endl--" << endl;
return 0;
}
运行结果:
装扮1
运动鞋
风衣
装扮的:lkmao
装扮2
西服
口罩
墨镜
装扮的:laoliu
--endl--
小结
装饰模式是为已有功能动态地添加更多功能的一种方式
当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为