基于原则设计
基于原则设计(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于其中。
外部链接