C++设计新思维——基于Policy的Class设计
Policy设计思路的来源:
软件设计,就是选择一种当前最优,而且在未来能得到很好扩展,便于维护的设计方案。通常都有多种可用的设计方案,而设计过程就是抉择的过程。
在软件设计中,常常会有这样的需求,对一个对象有大量的功能需求。此时常用的设计方案是:设计一个全功能型接口。然而,一个全功能型接口,将过于庞大,以至难以维护。好的设计应该是足够精巧的,而又清晰明了的。
故对于有大量功能需求的对象而言,全功能型接口不是好的选择。那么从另一个方向出发,则是将对象的功能分解,设计多个类来维护各种类型的接口,并尽量做到每个功能类的高内聚,功能类之间的低耦合。于是自然而然,产生这样的一种解法:多重继承。即对象实际所需功能是通过继承自多个功能类而得的。然而,多重继承的问题在于,“基类并没有足够的型别信息来完成它们的工作”。其实,我觉得这句话有点意思,举个例子:
1 #include <iostream> 2 #include <tr1/memory> 3 4 using std::cin ; 5 using std::cout ; 6 using std::endl ; 7 using std::tr1::shared_ptr ; 8 9 class WidgetNew ; 10 class WidgetStatic ; 11 12 class CreatorNew 13 { 14 public : 15 CreatorNew( ) { cout << "Create CreatorNew Obj ! " << endl ; } 16 17 ~CreatorNew( ) { cout << "Destroy CreatorNew Obj ! " << endl ; } 18 19 shared_ptr<WidgetNew> CreateObj( ); 20 } ; 21 22 class WidgetNew : public CreatorNew 23 { 24 public : 25 WidgetNew( ) { cout << "Create WidgetNew Obj !" << endl ; } 26 27 ~WidgetNew( ) { cout << "Destroy WidgetNew Obj !" << endl ; } 28 } ; 29 30 shared_ptr<WidgetNew> CreatorNew::CreateObj( ) 31 { 32 cout << "Create with new operator !" << endl ; 33 34 return shared_ptr<WidgetNew>( new WidgetNew( ) ); 35 } 36 37 class CreatorStatic 38 { 39 public : 40 CreatorStatic( ) { cout << "Create CreatorStatic Obj ! " << endl ; } 41 42 ~CreatorStatic( ) { cout << "Destroy CreatorStatic Obj ! " << endl ; } 43 44 WidgetStatic& CreateObj( ); 45 } ; 46 47 class WidgetStatic : public CreatorStatic 48 { 49 public : 50 WidgetStatic( ) { cout << "Create WidgetStatic Obj !" << endl ; } 51 52 ~WidgetStatic( ) { cout << "Destroy WidgetStatic Obj !" << endl ; } 53 } ; 54 55 WidgetStatic& CreatorStatic::CreateObj( ) 56 { 57 cout << "Create with static obj !" << endl ; 58 59 static WidgetStatic _wid ; 60 61 return _wid ; 62 } 63 64 int main( int argc, char **argv ) 65 { 66 cout << "------------- Create WidgetManager Object ! ------------" << endl ; 67 68 WidgetNew a_wid ; 69 70 WidgetStatic b_wid ; 71 72 cout << endl << "-- Create WidgetManager Object With CreateObj Method (New) ! --" << endl ; 73 74 a_wid.CreateObj( ) ; 75 76 cout << endl << "-- Create WidgetManager Object With CreateObj Method (Static) ! --" << endl ; 77 78 b_wid.CreateObj( ) ; 79 80 cout << endl << "------------ Destroy WidgetManager Object ! ------------" << endl ; 81 82 return 0 ; 83 }
其中对于Widget对象有两种Create功能,分别实现于CreatorNew和CreatorStatic中,然而Creator的目的是要创建具备该功能的子类对象,但是继承自Creator的子类是无限的,所以CreateObj接口的返回类型是可变的。可能有人会觉得,把Creator里的CreateObj接口声明为Virtual然后采用多态,不就解决了,有必要搞得那么复杂(我最初也是这样觉得的),可关键在于,多态要在运行期,才能确定最终的调用函数,而现在考虑的是要在编译期就确定下来,此外,当前的设计考虑的是将功能分解到多个类里面来管理,如果只是在一个超类里声明接口,而将实现放在具体的派生类,显然违背了设计的本意(本意是让各个类尽量精简,清晰明了)。所以我们不能采用多态的方式来解决。
故,单纯使用多重继承,并非好的选择。但是多重继承又是一个正确的思路,因为要么就将功能集中处理,也就是设计全功能接口,要么就将功能分解,也就是多重继承,显然多重继承是正确的。现在的问题是在于,多重继承时,派生类的类型对于超类是不可知的。所以最好的方法是让编译器能自动根据当前派生类实现出对应的超类。显然,具备这样特性的就是Template。于是乎,上述代码可修改如下:(测试地址:http://codepad.org/YsBxraK1 )
1 #include <iostream> 2 #include <tr1/memory> 3 4 using std::cin ; 5 using std::cout ; 6 using std::endl ; 7 using std::tr1::shared_ptr ; 8 9 template< class T > 10 class CreatorNew 11 { 12 public : 13 CreatorNew( ) { cout << "Create CreatorNew Obj ! " << endl ; } 14 15 ~CreatorNew( ) { cout << "Destroy CreatorNew Obj ! " << endl ; } 16 17 shared_ptr<T> CreateObj( ) 18 { 19 cout << "Create with new operator !" << endl ; 20 return shared_ptr<T>( new T( ) ); 21 } 22 } ; 23 24 template< class T > 25 class CreatorStatic 26 { 27 public : 28 CreatorStatic( ) { cout << "Create CreatorStatic Obj ! " << endl ; } 29 30 ~CreatorStatic( ) { cout << "Destroy CreatorStatic Obj ! " << endl ; } 31 32 T& CreateObj( ) 33 { 34 cout << "Create with static obj !" << endl ; 35 36 static T _t ; 37 38 return _t ; 39 } 40 } ; 41 42 43 template< template< class > class CreationPolicy > 44 class WidgetManager : public CreationPolicy< WidgetManager<CreationPolicy> > 45 { 46 public : 47 WidgetManager( ) { cout << "Create WidgetManager Obj !" << endl ; } 48 49 ~WidgetManager( ) { cout << "Destroy WidgetManager Obj !" << endl ; } 50 } ; 51 52 int main( int argc, char **argv ) 53 { 54 cout << "------------- Create WidgetManager Object ! ------------" << endl ; 55 56 WidgetManager< CreatorNew > a_wid ; 57 58 WidgetManager< CreatorStatic > b_wid ; 59 60 cout << endl << "-- Create WidgetManager Object With CreateObj Method (New) ! --" << endl ; 61 62 a_wid.CreateObj( ) ; 63 64 cout << endl << "-- Create WidgetManager Object With CreateObj Method (Static) ! --" << endl ; 65 66 b_wid.CreateObj( ) ; 67 68 cout << endl << "------------ Destroy WidgetManager Object ! ------------" << endl ; 69 70 return 0 ; 71 }
运行结果:
1 ------------- Create WidgetManager Object ! ------------ 2 Create CreatorNew Obj ! 3 Create WidgetManager Obj ! 4 Create CreatorStatic Obj ! 5 Create WidgetManager Obj ! 6 7 -- Create WidgetManager Object With CreateObj Method (New) ! -- 8 Create with new operator ! 9 Create CreatorNew Obj ! 10 Create WidgetManager Obj ! 11 Destroy WidgetManager Obj ! 12 Destroy CreatorNew Obj ! 13 14 -- Create WidgetManager Object With CreateObj Method (Static) ! -- 15 Create with static obj ! 16 Create CreatorStatic Obj ! 17 Create WidgetManager Obj ! 18 19 ------------ Destroy WidgetManager Object ! ------------ 20 Destroy WidgetManager Obj ! 21 Destroy CreatorStatic Obj ! 22 Destroy WidgetManager Obj ! 23 Destroy CreatorNew Obj ! 24 Destroy WidgetManager Obj ! 25 Destroy CreatorStatic Obj !