基於原則設計

基於原則設計(Policy-Based Class Design)又名policy-based class design 或 policy-based programming, 是一種基於C++電腦程式設計規範,以原則(Policy)為基礎,並結合C++的模板超編程(template metaprogramming)。policy-based首見於 Andrei Alexandrescu 出版的 《Modern C++ Design》 一書以及他在C/C++ Users Journal雜誌專欄 Generic<Programming> 。

概覽

[编辑]

Policy的意思是方針,或策略,也就是將原本複雜的系統,拆解成多個獨立運作的「策略類別」(policy class),每一組policy class都只负责单纯如行为(behavior, method)或结构(structure)的某一方面。Templetes與多重继承(Multiple Inheritance)两项技术互补。多重继承由於继承自多組 Base Class,故缺乏型别訊息(type information),而Templetes基於型别,擁有豐富的型别訊息。多重继承容易扩张,而Templetes的特化(Specialization)不容易扩张。Policy-Based Class Design 同時使用了 Template 以及 Multiple Inheritance 兩項技術,結合兩者的優點。

template <          class Policy1,          class Policy2,          class Policy3 > class PolicyBasedClass:public Policy1, public Policy2 { public:    PolicyBasedClass(){}; }; 

PolicyBasedClass則稱為宿主類別(host class),只需要切換不同 Policy Class,就可以得到不同的需求。Policy不一定要被宿主(host)继承,只需要用委托(delegation)完成这一工作。但policies必须遵守一个隐含的constraint,介面(interface)必须一样,故參數不能有巨大改變。

Policy class有點類似回呼函式(callbacks),但不同的是,callback只是一個函式,至於 policy class 則盡可能包含許多的 functions (methods), 有時還會結合狀態變數(state variables)與其他各式各樣的型別,如巢狀型別(nested types)。

policy 的一個重要的特徵是,宿主類別(host class)經常(並不一定要)使用多重繼承的機制去使用多個 policy classes. 因此在進行 policy 拆解時,必須要盡可能達成正交分解(Orthogonal Decomposition),policy彼此獨立運作,不相互影響。

Template Template Parameter

[编辑]

在 C++ 的Policy-Based Design 中,用來建構 Template 的類別參數(也就是policy class),本身亦可以是一個 Tempate 化的類別,形成所謂的 Template Template Parameter。

如果 Read()、Write() 有各種不同名目的參數時,可以利用 template 的不完全具現化 (Incomplement Instantiation) 特徵檢實現各個參數不同的成員函式(member function)。在host class中,可以撰寫不同參數版本的 Read(...) 函式,這有賴於c++ compiler的協助。

template < 	class T, 	template< class > class ReadPolicy, 	template< class > class WritePolicy > class ResourceManager 	: 	public ReadingPolicy< T >, 	public WritingPolicy< T > { public:    void Read();    void Write(XmlElement*);    void Write(DataSource*); }; 

上述的class T即是一個Template Template Parameter,這使得 Policy Class 更具擴充性與彈性,能夠處理各種類型的實體(instance)。

void main() {   ResourceManager< AnimationEntity, BinaryReader, BinaryWriter > ResMgr1;   ResourceManager< ScriptEntity, TextReader, TextWriter > ResMgr2; } 

範例

[编辑]

下例是 C++ hello world的範例,可以使用各種原則(policies)列印文字。

template<     typename output_policy,     typename language_policy > class HelloWorld   : public output_policy,     public language_policy {     using output_policy::Print;     using language_policy::Message;  public:      //behaviour method     void Run()     {         //two policy methods         Print( Message() );     }  };   #include <iostream>  class HelloWorld_OutputPolicy_WriteToCout { protected:      template< typename message_type >     void Print( message_type message )     {         std::cout << message << std::endl;     }  };   #include <string>  class HelloWorld_LanguagePolicy_English { protected:      std::string Message()     {         return "Hello, World!";     }  };  class HelloWorld_LanguagePolicy_German{ protected:      std::string Message()     {         return "Hallo Welt!";     }  };   int main() {  /* example 1 */      typedef         HelloWorld<             HelloWorld_OutputPolicy_WriteToCout,             HelloWorld_LanguagePolicy_English         >             my_hello_world_type;      my_hello_world_type hello_world;     hello_world.Run(); //returns Hello World!   /* example 2   * does the same but uses another policy, the language has changed  */      typedef         HelloWorld<             HelloWorld_OutputPolicy_WriteToCout,             HelloWorld_LanguagePolicy_German         >             my_other_hello_world_type;      my_other_hello_world_type hello_world2;     hello_world2.Run(); //returns Hallo Welt! } 

你可以更容易的撰寫其他的 Output policy, 單靠你創造更新的Policy class並實作print於其中。

外部連結

[编辑]