装饰器模式
1、引言
最近在看Openstack源码,发现里面大量使用了装饰器模式,以前也接触过装饰器模式,只了解它是在原有对象上加了一层封装,保持原有逻辑不变。今天仔细想想,完全可以再重新写一个类,把原来的对象包进去,将原来用到该对象的地方替换成现有对象即可,那为什么还要弄出来一个装饰器模式?
2、装饰器模式
允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰者可以在所委托被装饰者的行为之前或之后加上自己的行为,以达到特定的目的。
3、装饰器的结构
装饰器模式由组件和装饰者组成。
抽象组件(Component):需要装饰的抽象对象。
具体组件(ConcreteComponent):是我们需要装饰的对象
抽象装饰类(Decorator):内含指向抽象组件的引用及装饰者共有的方法。
具体装饰类(ConcreteDecorator):被装饰的对象。
4、装饰器的实现
由于是装饰的关系,这次我们用人和衣服当例子,衣服装饰人。首先定义一个被装饰的类表示人:
class Person { private: int id_; public: Person() : id_(0){} Person(int id) : id_(id){} virtual ~Person(){} virtual void Show(){ printf("%d\n",id_); } };
然后定义装饰类衣服:
class Clothes : public Person { public: Clothes() {} virtual ~Clothes() {} void Decorator(Person* p) { person_ = p; } virtual void Show() { if (person_) { person_->Show(); } } protected: Person* person_; };
最后实现具体的装饰类TShirt和Shoes:
class TShirt : public Clothes { public: void Show() { printf("TShirt "); person_->Show(); } }; class Shoes : public Clothes { public: void Show() { printf("Shoes "); person_->Show(); } };
调用装饰器装饰人:
void TestDecrator() { Person xa(110); TShirt shirt; Shoes shoes; shirt.Decorator(&xa); shoes.Decorator(&shirt); shoes.Show(); }
5、装饰器的优点
可以动态的给一个对象添加功能。
有效的把类的核心职责和装饰功能区分开。