目录
策略(policy)技术中的算法策略
- 算法逻辑分离,解耦合
常规范例:普通策略类
【引例】
//funcsum函数模板 template <typename T,typename U = SumFixedTraits<T> > auto funcsum(const T* begin, const T* end) { typename U::sumT sum = U::initValue(); for (;;) { sum += (*begin); if (begin == end) break; ++begin; }//end for return sum; }
- 这是前面的案例,其中可以把funcsum求和看成是一种算法,但是这样就只能求和,若是要求乘除等就得重新写。
【使用策略】
//求和策略类以实现求和算法。 struct SumPolicy { //静态成员函数模板 template <typename sumT, typename T> //sumT是和值类型,T是数组元素类型 static void algorithm(sumT& sum, const T& value) //策略类的核心算法 { sum += value; //求和 } }; template <typename T, typename U = SumFixedTraits<T> ,typename V = SumPolicy> auto funcsum(const T* begin, const T* end) { typename U::sumT sum = U::initValue(); for (;;) { V::algorithm(sum, *begin); if (begin == end) break; ++begin; }//end for return sum; }
- 调用
char mychararray[] = "abc"; cout << (int)(funcsum(&mychararray[0], &mychararray[2])) << endl;
【最小值策略】
template <typename T> struct MinFixedTraits; template<> struct MinFixedTraits<int> { using sumT = int; //求最小值,结果类型与元素类型相同即可,为了名字统一,都用sumT这个名字 static sumT initValue() { return INT_MAX; } //INT_MAX:整型最大值,任何一个数组元素都不会被这个值更大 //因此可以顺利的找到数组元素中的最小值,参见MinPolicy::algorithm }; //求最小值策略类 struct MinPolicy { template <typename minT, typename T> static void algorithm(minT& min, const T& value) { if (min > value) min = value; } };
- 调用
int myintarray1[] = { 10,15,20 }; cout << (int)(funcsum<int, MinFixedTraits<int>, MinPolicy>(&myintarray1[0], &myintarray1[2])) << endl;
常规范例:策略类模板
- 上面的类通过在普通类中使用静态成员函数模板实现策略。
- 下面将普通类改成类模板。
//求和策略类以实现求和算法。 template <typename sumT, typename T> struct SumPolicy { //静态成员函数模板 static void algorithm(sumT& sum, const T& value) //策略类的核心算法 { sum += value; //求和 } }; //求最小值策略类 template <typename minT, typename T> struct MinPolicy { static void algorithm(minT& min, const T& value) { if (min > value) min = value; } };
//funcsum函数模板 template <typename T, typename U = SumFixedTraits<T> , template<class,class> class V = SumPolicy //这里class也可以写成typename > auto funcsum(const T* begin, const T* end) { typename U::sumT sum = U::initValue(); //typename SumFixedTraits<char>::sumT sum = SumFixedTraits<char>::initValue(); //int sum = 0; for (;;) { V<U::sumT,T>::algorithm(sum, *begin); //捋一下:T是数组成员类型,U是固定萃取(fixed traits)类模板, //从中可以提取出结算的结果类型(U::sumT)以及结果的初值, //V是策略类模板,用于实现具体算法(求和,求最小值等) if (begin == end) break; ++begin; }//end for return sum; }
- 调用
int myintarray1[] = { 10,15,20 }; cout << (int)(funcsum<int, MinFixedTraits<int>, MinPolicy>(&myintarray1[0], &myintarray1[2])) << endl;
【总结】萃取(trait)技术与策略(policy)技术的思想
- 两种技术都象一个中间件一样,夹在不同的功能代码之间,让代码之间的调用更加灵活。
- 萃取技术:给进去一个类型,萃取出另外一个类型或者另外一个值(注重于类型或者指定)。
- 策略技术:给进去一个类型,萃取出一个算法或者是一个不同的功能实现(注重于动作或者行为)。
- 因此,在书写策略类(类模板)的时候通常都需要包含(静态)成员函数以实现指定的行为。
- 有时,萃取技术中也可能实现某些动作或者行为,所以从这个角度来讲,萃取技术与策略技术有时区分不是那么明显。
- 萃取技术一般通过一个类模板来实现,通常包含类模板的泛化版本和多个特化版本。
- 策略技术用普通类或者类模板都可以实现。