decorator pattern -- 装饰模式

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

举例,一辆汽车

 1 class car
 2 {
 3     public:
 4         virtual void turnLeft( )=0;
 5         virtual void turnRight( )=0;
 6         virtual void goBack( )=0;
 7         virtual void goAhead( )=0;
 8         //制动距离
 9         virtual void getDistance( ){...}
10     protected:
11         int speed;
12 };
有三两不同排量的车,那么对应它们操作细节也有些不同
那么我们会理所当然的继承上面抽象类car。
 1 class car2L:public car
 2 {
 3     public:
 4         virtual void turnLeft( ){...}
 5         virtual void turnRight( ){...}
 6         virtual void goBack( ){...}
 7         virtual void goAhead( ){...}
 8         virtual void getDistance( ){...}
 9     protected:
10         static const int maxSpeed; 
11 };
12 const int car2L::maxSpeed=450;
13 
14 class car1.8L:public car
15 {
16     public:
17         virtual void turnLeft( ){...}
18         virtual void turnRight( ){...}
19         virtual void goBack( ){...}
20         virtual void goAhead( ){...}
21         virtual void getDistance( ){...}
22     protected:
23         static const int maxSpeed;
24 };
25 const int car1.8L::maxSpeed=400;
26 
27 class car1.5L:public car
28 {
29     public:
30         virtual void turnLeft( ){...}
31         virtual void turnRight( ){...}
32         virtual void goBack( ){...}
33         virtual void getAhead( ){...}
34         virtual void getDistance( ){...}
35     protected:
36         static const int maxSpeed;
37 }
38 const int car1.5L::maxSpeed=350;

那么现在又多出了3个汽车品牌:Audi,Benz,Ferrari那么又会在原来基础上增加功能

  1 class car2LAudi:public car2L
  2 {
  3     public:
  4         virtual void turnLeft( ){...}
  5         virtual void turnRight( ){...}
  6         virtual void goBack( ){...}
  7         virtual void goAhead( ){...}
  8         virtual void getDistance( ){...}
  9         ...
 10     protected:
 11         static const int maxSpeed; 
 12 };
 13 const int car2LAudi::maxSpeed=480;
 14 
 15 class car1.8LAudi:public car1.8L
 16 {
 17     public:
 18         virtual void turnLeft( ){...}
 19         virtual void turnRight( ){...}
 20         virtual void goBack( ){...}
 21         virtual void goAhead( ){...}
 22         virtual void getDistance( ){...}
 23         ...
 24     protected:
 25         static const int maxSpeed;
 26 };
 27 const int car1.8LAudi::maxSpeed=430;
 28 
 29 class car1.5LAudi:public car1.5L
 30 {
 31     public:
 32         virtual void turnLeft( ){...}
 33         virtual void turnRight( ){...}
 34         virtual void goBack( ){...}
 35         virtual void getAhead( ){...}
 36         virtual void getDistance( ){...}
 37         ...
 38     protected:
 39         static const int maxSpeed;
 40 }
 41 const int car1.5LAudi::maxSpeed=380;
 42 
 43 class car2LBenz:public car2L
 44 {
 45     public:
 46         virtual void turnLeft( ){...}
 47         virtual void turnRight( ){...}
 48         virtual void goBack( ){...}
 49         virtual void goAhead( ){...}
 50         virtual void getDistance( ){...}
 51         ...
 52     protected:
 53         static const int maxSpeed; 
 54 };
 55 const int car2LBenz::maxSpeed=450;
 56 
 57 class car1.8LBenz:public car1.8L
 58 {
 59     public:
 60         virtual void turnLeft( ){...}
 61         virtual void turnRight( ){...}
 62         virtual void goBack( ){...}
 63         virtual void goAhead( ){...}
 64         virtual void getDistance( ){...}
 65         ...
 66     protected:
 67         static const int maxSpeed;
 68 };
 69 const int car1.8LBenz::maxSpeed=400;
 70 
 71 class car1.5LBenz:public car1.5L
 72 {
 73     public:
 74         virtual void turnLeft( ){...}
 75         virtual void turnRight( ){...}
 76         virtual void goBack( ){...}
 77         virtual void getAhead( ){...}
 78         virtual void getDistance( ){...}
 79         ..
 80     protected:
 81         static const int maxSpeed;
 82 }
 83 const int car1.5LBenz::maxSpeed=350;
 84 
 85 class car2LAudi:public car2L
 86 {
 87     public:
 88         virtual void turnLeft( ){...}
 89         virtual void turnRight( ){...}
 90         virtual void goBack( ){...}
 91         virtual void goAhead( ){...}
 92         virtual void getDistance( ){...}
 93         ...
 94     protected:
 95         static const int maxSpeed; 
 96 };
 97 const int car2LAudi::maxSpeed=480;
 98 
 99 class car1.8LAudi:public car1.8L
100 {
101     public:
102         virtual void turnLeft( ){...}
103         virtual void turnRight( ){...}
104         virtual void goBack( ){...}
105         virtual void goAhead( ){...}
106         virtual void getDistance( ){...}
107         ...
108     protected:
109         static const int maxSpeed;
110 };
111 const int car1.8LAudi::maxSpeed=430;
112 
113 class car1.5LAudi:public car1.5L
114 {
115     public:
116         virtual void turnLeft( ){...}
117         virtual void turnRight( ){...}
118         virtual void goBack( ){...}
119         virtual void getAhead( ){...}
120         virtual void getDistance( ){...}
121         ...
122     protected:
123         static const int maxSpeed;
124 }
125 const int car1.5LAudi::maxSpeed=380;
126 
127 class car2LFerrari:public car2L
128 {
129     public:
130         virtual void turnLeft( ){...}
131         virtual void turnRight( ){...}
132         virtual void goBack( ){...}
133         virtual void goAhead( ){...}
134         virtual void getDistance( ){...}
135         ...
136     protected:
137         static const int maxSpeed; 
138 };
139 const int car2LFerrari::maxSpeed=550;
140 
141 class car1.8LFerraripublic car1.8L
142 {
143     public:
144         virtual void turnLeft( ){...}
145         virtual void turnRight( ){...}
146         virtual void goBack( ){...}
147         virtual void goAhead( ){...}
148         virtual void getDistance( ){...}
149         ...
150     protected:
151         static const int maxSpeed;
152 };
153 const int car1.8LFerrari::maxSpeed=500;
154 
155 class car1.5LFerrari:public car1.5L
156 {
157     public:
158         virtual void turnLeft( ){...}
159         virtual void turnRight( ){...}
160         virtual void goBack( ){...}
161         virtual void getAhead( ){...}
162         virtual void getDistance( ){...}
163         ..
164     protected:
165         static const int maxSpeed;
166 }
167 const int car1.5LFerrari::maxSpeed=450;
如果这里在做一个分类高档,中档,抵挡,继承上面各类,那么又需要写27个类。如果中间我们需要增加任何一个类的品种,都会增加对应的子类。上面有这么类原因是,准备好所有需要用到的类,必须在代码编译之前准备好。
上描述的问题根源在于我们过度使用了继承来扩展对象的功能,由于继承为类型引入的静态特质(必须在编译之前将所有类准备好),使得这种扩展方式缺乏灵活性;并且随着子类和扩展品种的增多,各种子类和扩展功能组合导致子类的数量以几何级数方式增长,以至代码难以维护。
装饰模式则是相对于上面“静态”为“动态”。
例如我们在上面基础上通过使用装饰模式加品牌。
 1 class car
 2 {};
 3 class car2L:public car
 4 {};
 5 class car1.8L:public car
 6 {}
 7 class car1.5L:public car
 8 {}
 9 class decorator:public car
10 {
11     ...
12     ...
13     protected:
14         car * car;
15 };
16 class AudiDecorator:public decorator
17 {
18     public:
19         virtual void turnLeft( )
20         {
21             ...
22             增加有这个品牌的变化代码
23         }
24         ...
25 };
26 class BenzDecorator:public decorator
27 {
28     public:
29         virtual void turnLeft( )
30         {
31             ...
32             增加有这个品牌的变化代码
33         }
34         ...
35 };
36 class FerrariDecorator:public decorator
37 {
38     public:
39         virtual void turnLeft( )
40         {
41             ...
42             增加有这个品牌的变化代码
43         }
44         ...
45 };
46 
47 int 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     ...
60     return 0;
61 }

 

posted @ 2012-12-20 00:04  胡佳180815  阅读(1263)  评论(0编辑  收藏  举报