|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
编程范型 |
| --- |
|  |
| 指令式 | 
* 过程式
* 块结构
* 例外处理
* 结构化
* 模块化

 |
|  |
| 函数式 | 
* 头等函数
* 纯函数式
* 隐式
* 模式匹配
* 推导式

 |
|  |
| 面向对象 | 
* 基于类
* 基于原型
* 契约式
* 面向方面
* 面向代理

 |
|  |
| 数据流程 | 
* 同步式
* 响应式
	+ 函数式响应式
* 串流处理
* 基于流程

 |
|  |
| 宣告式 | 
* 逻辑式
	+ 回答集
* 约束式
* 数据查询
* 框架本体

 |
|  |
|  | 
* 协程
* 演员模型
* 通信顺序进程
* future/promise
* 分叉会合
* 整体同步
* 映射归约

 |
|  |
| 其他 | 
* 递归
* 阵列式
* 多态
	+ 运算符重载
	+ 泛型
	+ 多分派
* 面向堆栈
* 非确定性
* 数据驱动
* 事件驱动
* 自动机
* 可微分
* 概率式

 |
|  |
| 按语言比较（英语：） |

 |

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

外部連結
----

* Andrei Alexandrescu's Web site