装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
Component定义了一个对象的接口,可以给这些对象动态的添加职责。ConcreteComponent定义了一个具体的对象。也可以给这个对象增加职责。Decorator,装饰抽象类,继承了Component,从外类来扩展Component的功能。但对于Component来说是无需知道Decorator的存在的。ConcreteComponent是具体的装饰对象。起到给Component增加功能的作用。
#include<iostream>
using namespace std;
class Component
{
public:
virtual void Operation()=0;
};
class ConcreteComponent:public Component
{
public:
virtual void Operation()
{
std::cout<<"具体的抽象对象!"<<std::endl;
}
};
class Decorator:public Component
{
public:
Decorator()
{
component=NULL;
}
void setComponent(Component *c)
{
component=c;
}
virtual void Operation()
{
if(component)
{
component->Operation();
}
}
protected:
Component *component;
};
class ConcreteDecoratorA:public Decorator
{
public:
ConcreteDecoratorA()
:Decorator()
{
}
virtual void Operation()
{
if(component)
{
component->Operation();
show();
}
}
void show()
{
std::cout<<"I am the unique function of ConcreteDecoratorA"<<std::endl;
}
};
class ConcreteDecoratorB:public Decorator
{
public:
ConcreteDecoratorB()
:Decorator()
{
}
virtual void Operation()
{
if(component)
{
component->Operation();
show();
}
}
void show()
{
std::cout<<"I am the unique function of ConcreteDecoratorB"<<std::endl;
}
};
int main(int argc,char**argv)
{
ConcreteComponent *cc=new ConcreteComponent;
ConcreteDecoratorA *cda=new ConcreteDecoratorA;
ConcreteDecoratorB *cdb=new ConcreteDecoratorB;
cda->setComponent(cc);
cdb->setComponent(cda);//Decorator要派生自Component否则就无法执行此操作。
cdb->Operation();
return 0;
}
装饰模式利用setComponent对对象进行包装,这样每个装饰对象的实现就和如何使用这个对象分离,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链中。
装饰模式是为已有对象动态添加功能的一种方式。在系统需要新功能的时候,我们可以通过向旧类中添加代码实现目的。这些新增加的代码通常装饰了原有类的核心职责或主要行为。向主类增加代码后,会增加主类的复杂度,而这些新增加的代码仅仅是为了满足某些特殊的情况下才会执行的行为的需要。而装饰模式却提供了一个非常好的方案。它把每个要装饰的类放在单独的类中。并让这些类包装它所装饰的对象。当需要执行特殊行为时,客户就可以在运行时根据需要有选择的、按顺序的使用装饰功能包装对象。
装饰功能的优点:把装饰功能从类中搬移,这可以降低原有类的复杂度。有效地把类的核心功能与装饰功能分开,同时还可以去除相关类的重复装饰逻辑。
以下为《大话设计模式》第六章衣服搭配例子的C++版本代码:
#include<iostream>
#include<string>
using namespace std;
class Person//ConcreteComponent类
{
public:
string name;
public:
Person()
{
}
Person(string name)
{
this->name=name;
}
virtual void show()
{
std::cout<<"装饰的"<<name<<std::endl;
}
};
class Clothes:public Person//Decorator类。
{
public:
Person *p;
public:
Clothes()
{
p=NULL;
}
void decorate(Person*pp)
{
p=pp;
}
virtual void show()
{
if(p)
{
p->show();
}
}
};
class kuaiku:public Clothes//ConcreteDecorator类。
{
public:
kuaiku()
{
}
virtual void show()
{
std::cout<<"垮裤"<<std::endl;
Clothes::show();//也可以使用p->show();
}
};
class dakucha:public Clothes//ConcreteDecorator类。
{
public:
dakucha()
{
}
virtual void show()
{
std::cout<<"大裤衩"<<std::endl;
Clothes::show();//也可以使用p->show();
}
};
class LeatherShoe:public Clothes//ConcreteDecorator类。
{
public:
LeatherShoe()
{
}
virtual void show()
{
std::cout<<"皮鞋"<<std::endl;
Clothes::show();//也可以使用p->show();
}
};
class Xizhuang:public Clothes//ConcreteDecorator类。
{
public:
Xizhuang()
{
}
virtual void show()
{
std::cout<<"西装"<<std::endl;
Clothes::show();//也可以使用p->show();
}
};
int main(int argc,char**argv)
{
Person *p=new Person("ithzhang");
kuaiku *kk=new kuaiku();
dakucha *dkc=new dakucha();
LeatherShoe*ls=new LeatherShoe();
kk->decorate(p);
dkc->decorate(kk);
ls->decorate(dkc);
ls->show();
return 0;
}