For faster navigation, this Iframe is preloading the Wikiwand page for 基於原則設計.

基於原則設計

基於原則設計(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於其中。

外部連結


{{bottomLinkPreText}} {{bottomLinkText}}
基於原則設計
Listen to this article

This browser is not supported by Wikiwand :(
Wikiwand requires a browser with modern capabilities in order to provide you with the best reading experience.
Please download and use one of the following browsers:

This article was just edited, click to reload
This article has been deleted on Wikipedia (Why?)

Back to homepage

Please click Add in the dialog above
Please click Allow in the top-left corner,
then click Install Now in the dialog
Please click Open in the download dialog,
then click Install
Please click the "Downloads" icon in the Safari toolbar, open the first download in the list,
then click Install
{{::$root.activation.text}}

Install Wikiwand

Install on Chrome Install on Firefox
Don't forget to rate us

Tell your friends about Wikiwand!

Gmail Facebook Twitter Link

Enjoying Wikiwand?

Tell your friends and spread the love:
Share on Gmail Share on Facebook Share on Twitter Share on Buffer

Our magic isn't perfect

You can help our automatic cover photo selection by reporting an unsuitable photo.

This photo is visually disturbing This photo is not a good choice

Thank you for helping!


Your input will affect cover photo selection, along with input from other users.

X

Get ready for Wikiwand 2.0 🎉! the new version arrives on September 1st! Don't want to wait?