Policy Based Design

本文将介绍Policy-based design

在基于策略的设计中,最主要的习惯用法是一个类模板(称为宿主类),它以几个类型参数作为输入,用用户选择的类型(称为策略类)实例化,每个类型都实现一个特定的隐式接口(称为策略),以及封装实例化的宿主类行为的一些正交(或大部分正交)方面。通过为每个策略提供一个与一组不同的、封闭的实现相结合的宿主类,库或模块可以支持指数级的不同行为组合,在编译时进行解析,并通过在主机类模板的实例化中混合和匹配不同提供的策略类来进行选择。

例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <iostream>
#include <stdio.h>
using namespace std;

//-- two POLCIES AS BELOW i.e. NoChecking , EnforceNotNull -------------
//------- 1st POLICY ------------------------

template <class T>
struct NoChecking {
   static void Check(T* t){
     if(t == NULL)
      std::cout<<std::endl<<"NoChecking : Value is NULL "<<std::endl;
    else
      std::cout<<std::endl<<"NoChecking : Value is NOT NULL "<<std::endl;
   }
 };
1
2
3
4
5
6
7
8
//------------- 2nd POLICY ----------------------------
template <class T>
struct EnforceNotNull {
  class NullPointerException : public std::exception {  };
  static void Check(T* ptr) {
    if (!ptr) throw NullPointerException();
  }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// 此处使用了template template parameters, 使得模板policy使用同样的类型T进行实例化
template <class T, template <class> class CheckingPolicy>
class SmartPtr : public CheckingPolicy<T> {
public:
  SmartPtr(T* t=NULL) {
    if(t!=NULL) {
      pointee_ = t;
    }
  }
  ~SmartPtr(void) {
    if(pointee_!=NULL) {
      delete pointee_;
    }
  }
  T* operator->() {
    CheckingPolicy<T>::Check(pointee_);
    return pointee_;
  }
private:
  T* pointee_;
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class A {
public:
  A() {
    std::cout<<std::endl<<"A Constructor"<<std::endl;
  }
  ~A() {
    std::cout<<std::endl<<"A Destructor"<<std::endl;
  }
 void MyName(void) {
   std::cout<<std::endl<<"I am instance of class A ...."<<std::endl;
 }
};

typedef SmartPtr<A, NoChecking> ClassA_Ptr;
typedef SmartPtr<A, EnforceNotNull> SafeClassA_Ptr;

int main(int argc, char* argv[]) {
 ClassA_Ptr aptr = new A;
 aptr->MyName();
 SafeClassA_Ptr safe_aptr = new A;
 safe_aptr->MyName();
 return 0;
}

updatedupdated2021-11-062021-11-06