Decorator,装饰模式
就是使“对象功能的扩展”能够根据需要来动态地实现,同时可以避免“扩展功能的增多”导致子类数量急剧增多,从而使得任何“功能扩展变化”所产生的负面影响降为最低。
Decorator提供了一种给类增加职责的方法,不是通过继承实现,而是组合。

举例,一辆汽车
1class car 2{ 3public: 4virtualvoid turnLeft( )=0; 5virtualvoid turnRight( )=0; 6virtualvoid goBack( )=0; 7virtualvoid goAhead( )=0; 8//制动距离 9virtualvoid getDistance( ){...}10protected:11int speed;12 };
有三两不同排量的车,那么对应它们操作细节也有些不同
那么我们会理所当然的继承上面抽象类car。
1class car2L:public car 2{ 3public: 4virtualvoid turnLeft( ){...} 5virtualvoid turnRight( ){...} 6virtualvoid goBack( ){...} 7virtualvoid goAhead( ){...} 8virtualvoid getDistance( ){...} 9protected:10staticconstint maxSpeed; 11};12constint car2L::maxSpeed=450;1314class car1.8L:public car15{16public:17virtualvoid turnLeft( ){...}18virtualvoid turnRight( ){...}19virtualvoid goBack( ){...}20virtualvoid goAhead( ){...}21virtualvoid getDistance( ){...}22protected:23staticconstint maxSpeed;24};25constint car1.8L::maxSpeed=400;2627class car1.5L:public car28{29public:30virtualvoid turnLeft( ){...}31virtualvoid turnRight( ){...}32virtualvoid goBack( ){...}33virtualvoid getAhead( ){...}34virtualvoid getDistance( ){...}35protected:36staticconstint maxSpeed;37}38constint car1.5L::maxSpeed=350;
那么现在又多出了3个汽车品牌:Audi,Benz,Ferrari那么又会在原来基础上增加功能
1class car2LAudi:public car2L 2{ 3public: 4virtualvoid turnLeft( ){...} 5virtualvoid turnRight( ){...} 6virtualvoid goBack( ){...} 7virtualvoid goAhead( ){...} 8virtualvoid getDistance( ){...} 9 ... 10protected: 11staticconstint maxSpeed; 12}; 13constint car2LAudi::maxSpeed=480; 14 15class car1.8LAudi:public car1.8L 16{ 17public: 18virtualvoid turnLeft( ){...} 19virtualvoid turnRight( ){...} 20virtualvoid goBack( ){...} 21virtualvoid goAhead( ){...} 22virtualvoid getDistance( ){...} 23 ... 24protected: 25staticconstint maxSpeed; 26}; 27constint car1.8LAudi::maxSpeed=430; 28 29class car1.5LAudi:public car1.5L 30{ 31public: 32virtualvoid turnLeft( ){...} 33virtualvoid turnRight( ){...} 34virtualvoid goBack( ){...} 35virtualvoid getAhead( ){...} 36virtualvoid getDistance( ){...} 37 ... 38protected: 39staticconstint maxSpeed; 40} 41constint car1.5LAudi::maxSpeed=380; 42 43class car2LBenz:public car2L 44{ 45public: 46virtualvoid turnLeft( ){...} 47virtualvoid turnRight( ){...} 48virtualvoid goBack( ){...} 49virtualvoid goAhead( ){...} 50virtualvoid getDistance( ){...} 51 ... 52protected: 53staticconstint maxSpeed; 54}; 55constint car2LBenz::maxSpeed=450; 56 57class car1.8LBenz:public car1.8L 58{ 59public: 60virtualvoid turnLeft( ){...} 61virtualvoid turnRight( ){...} 62virtualvoid goBack( ){...} 63virtualvoid goAhead( ){...} 64virtualvoid getDistance( ){...} 65 ... 66protected: 67staticconstint maxSpeed; 68}; 69constint car1.8LBenz::maxSpeed=400; 70 71class car1.5LBenz:public car1.5L 72{ 73public: 74virtualvoid turnLeft( ){...} 75virtualvoid turnRight( ){...} 76virtualvoid goBack( ){...} 77virtualvoid getAhead( ){...} 78virtualvoid getDistance( ){...} 79 .. 80protected: 81staticconstint maxSpeed; 82} 83constint car1.5LBenz::maxSpeed=350; 84 85class car2LAudi:public car2L 86{ 87public: 88virtualvoid turnLeft( ){...} 89virtualvoid turnRight( ){...} 90virtualvoid goBack( ){...} 91virtualvoid goAhead( ){...} 92virtualvoid getDistance( ){...} 93 ... 94protected: 95staticconstint maxSpeed; 96}; 97constint car2LAudi::maxSpeed=480; 98 99class car1.8LAudi:public car1.8L100{101public:102virtualvoid turnLeft( ){...}103virtualvoid turnRight( ){...}104virtualvoid goBack( ){...}105virtualvoid goAhead( ){...}106virtualvoid getDistance( ){...}107 ...108protected:109staticconstint maxSpeed;110};111constint car1.8LAudi::maxSpeed=430;112113class car1.5LAudi:public car1.5L114{115public:116virtualvoid turnLeft( ){...}117virtualvoid turnRight( ){...}118virtualvoid goBack( ){...}119virtualvoid getAhead( ){...}120virtualvoid getDistance( ){...}121 ...122protected:123staticconstint maxSpeed;124}125constint car1.5LAudi::maxSpeed=380;126127class car2LFerrari:public car2L128{129public:130virtualvoid turnLeft( ){...}131virtualvoid turnRight( ){...}132virtualvoid goBack( ){...}133virtualvoid goAhead( ){...}134virtualvoid getDistance( ){...}135 ...136protected:137staticconstint maxSpeed; 138};139constint car2LFerrari::maxSpeed=550;140141class car1.8LFerraripublic car1.8L142{143public:144virtualvoid turnLeft( ){...}145virtualvoid turnRight( ){...}146virtualvoid goBack( ){...}147virtualvoid goAhead( ){...}148virtualvoid getDistance( ){...}149 ...150protected:151staticconstint maxSpeed;152};153constint car1.8LFerrari::maxSpeed=500;154155class car1.5LFerrari:public car1.5L156{157public:158virtualvoid turnLeft( ){...}159virtualvoid turnRight( ){...}160virtualvoid goBack( ){...}161virtualvoid getAhead( ){...}162virtualvoid getDistance( ){...}163 ..164protected:165staticconstint maxSpeed;166}167constint car1.5LFerrari::maxSpeed=450;
如果这里在做一个分类高档,中档,抵挡,继承上面各类,那么又需要写27个类。如果中间我们需要增加任何一个类的品种,都会增加对应的子类。上面有这么类原因是,准备好所有需要用到的类,必须在代码编译之前准备好。
上描述的问题根源在于我们过度使用了继承来扩展对象的功能,由于继承为类型引入的静态特质(必须在编译之前将所有类准备好),使得这种扩展方式缺乏灵活性;并且随着子类和扩展品种的增多,各种子类和扩展功能组合导致子类的数量以几何级数方式增长,以至代码难以维护。
装饰模式则是相对于上面“静态”为“动态”。
例如我们在上面基础上通过使用装饰模式加品牌。
1class car 2{}; 3class car2L:public car 4{}; 5class car1.8L:public car 6{} 7class car1.5L:public car 8{} 9class decorator:public car10{11 ...12 ...13protected:14 car * car;15};16class AudiDecorator:public decorator17{18public:19virtualvoid turnLeft( )20 {21 ...22 增加有这个品牌的变化代码23 }24 ...25};26class BenzDecorator:public decorator27{28public:29virtualvoid turnLeft( )30 {31 ...32 增加有这个品牌的变化代码33 }34 ...35};36class FerrariDecorator:public decorator37{38public:39virtualvoid turnLeft( )40 {41 ...42 增加有这个品牌的变化代码43 }44 ...45};4647int main( int argc,char ** argv)48{49 car2L * c=new car2L( );50//相当于动态构造奔驰排量2L的车,相当于原先的car2LBenz类51 BenzDecorator b=new BenzDecorator(c);52 b->turnLeft( );53 b->turnRight( );54 ...55//相当于动态构造法拉利排量2L的车,相当于原先的car2LFerrari类56 FerrariDecorator f=new FerrariDecorator(c);57 f->turnLeft( );58 f->turnRight( );59 ...60return0;61 }