上周换了家公司,由于项目还没有开始,所以比较清闲,上班没事捣鼓下了装饰模式,下面来做做笔记。
装饰模式:动态的将职责额外的加到对象上,若是要扩展,装饰模式提供比继承更加灵活。
上面定义可能比较羞涩难明白,我们举个例子。如世界有英语课程,英语课程很多国家又各有不同,如果中国英语。中国英文又分为新东方英语,新概念英语等,这些英语有些共同的地方,也有些各自特色的地方。如果用OO表示,我们应该怎么表示那?将英语课程定义为基类,让不同国家英语继承它,再定义一个装饰类,继承自英语基类,最后再定义新概念新东方英语类,继承自装饰类,并在新东方和新概念类里增加个性化的东西(这点很重要,不是新增类,而是新组合个性化的东西),不就实现了吗。具体我们可以看看UML类图:
再来看看代码(这一刻,更清晰......):
#include <iostream> using namespace std; class English //英语基类---》抽象公共类 { public: virtual void show()=0; virtual ~English(){} }; class ChinaEnglish : public English //中国英语----》具体类 { public: virtual void show() { cout<<"China English :"; } }; class DecoratorEnglish : public English //装饰英文类----》装饰基类 { private: English* m_english; public: DecoratorEnglish(English* en):m_english(en){} virtual void show() { m_english->show(); } }; class NewOrientalDecoratorEnglish : public DecoratorEnglish//新东方英语-----》具体装饰类 { public: NewOrientalDecoratorEnglish(English* en):DecoratorEnglish(en){} virtual void show() { DecoratorEnglish::show(); setNewOrientalEnglish(); cout<<endl; } private: void setNewOrientalEnglish() { cout<<"New Orienttal english ."<<endl; } }; class NewConceptDecoratorEnglish : public DecoratorEnglish//新概念英语-----》具体装饰类 { public: NewConceptDecoratorEnglish(English* en):DecoratorEnglish(en){} virtual void show() { DecoratorEnglish::show(); setNewConceptEnglish(); cout<<endl; } private: void setNewConceptEnglish() { cout<<"New Concept english ."<<endl; } }; int main(int argc, char** argv) { English* eng = new ChinaEnglish; English* DecA = new NewOrientalDecoratorEnglish(eng); English* DecB = new NewConceptDecoratorEnglish(eng); DecA->show(); DecB->show(); delete eng; delete DecA; delete DecB; return 0; }
输出结果如下:
现在来总结下上面的笔记。上面新东方和新概念英语类,没有使用继承来增加个性化的东西,而是使用组合的方法,有效的把核心东西和个性化东西组合,且不不重复,这就是装饰模式的核心。