装饰模式(decorator ):动态的给一个对象添加一些额外的职责,就增加的功能来说,装饰模式比生成子类更为灵活。
使用情况:当系统需要新功能的时候,是想旧的类中添加新的代码,这些新的代码通常装饰了原有类的核心职责或者主要行为,它们在主类中加入了新的字段,新的方法新的逻辑,从而增加了主类的复杂度。而这些新加入的东西仅仅是为了满足一些只有在特定情况下才会执行的特殊行为的需要。装饰模式可以把每个要装饰的功能放在单独的类中,并让这个类包装它要装饰的对象,所以,当执行特殊行为是,客户代码就可以在运行的时候根据需要有选择的,按顺序的使用装饰功能包装对象了。
优点:有效地把类的核心职能和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。
#ifndef DECORATOR_H
#define DECORATOR_H
#include<iostream>
#include<string>
using namespace std;
class Person
{
string name;
public:
Person(){}
Person(string st) :name(st){}
virtual void Show()const;
};
class Finery :public Person
{
protected:
Person *component;
public:
//Finery(){}
void Decorate(Person * component)
{
this->component = component;
}
virtual void Show()const;
};
class Tshirt :public Finery
{
public:
//Tshirt(){}
void Show()const;
};
class BigTrouser :public Finery
{
public:
//BigTrouser(){}
void Show()const;
};
class BrokeSportShoes :public Finery
{
public:
//BrokeSportShoes(){}
void Show()const;
};
class Suit :public Finery
{
public:
//Suit(){}
void Show()const;
};
class Tie :public Finery
{
public:
//Tie(){}
void Show()const;
};
class LeatherShoes :public Finery
{
public:
//LeatherShoes(){}
void Show()const;
};
void Person::Show()const
{
cout << " decorator " << name << endl;
}
void Finery::Show()const
{
if (&component != NULL)
component->Show();
}
void Tshirt::Show()const
{
cout << "T shirt ";
component->Show();
}
void BigTrouser::Show()const
{
cout << "BigTrouser ";
component->Show();
}
void BrokeSportShoes::Show()const
{
cout << "BrokeSportShoes ";
component->Show();
}
void Suit::Show()const
{
cout << "Suit ";
component->Show();
}
void Tie::Show()const
{
cout << "Tie ";
component->Show();
}
void LeatherShoes::Show()const
{
cout << "LeatherShoes ";
component->Show();
}
#endif
#include"Decorator.h"
int main()
{
Person xr("Summer Liu");
cout << "The first decorator:\n";
Tshirt * Ts = new Tshirt;
BigTrouser * BigT = new BigTrouser;
BrokeSportShoes * BrokeS = new BrokeSportShoes;
Suit * Suit_ = new Suit;
Ts->Decorate(&xr);
BigT->Decorate(Ts);
BrokeS->Decorate(BigT);
BrokeS->Show();
Suit_->Decorate(BrokeS);
Suit_->Show();
return 0;
}