设为首页 加入收藏

TOP

decorator pattern -- 装饰模式
2013-01-01 14:40:39 来源: 作者: 【 】 浏览:299
Tags:decorator pattern 装饰 模式
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 }

 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇VC++查找替换对话框 下一篇composite pattern -- 组合模式

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: