频道栏目
首页 > 程序开发 > 软件开发 > 其他 > 正文
Generic design | Policies 和Policy Classes
2016-09-16 09:32:15         来源:sweeterer  
收藏   我要投稿

注意:本系列博文需要对templates和STL有一定掌握。

Policies 和Policy Classes

承接上一篇博文所述,这回将介绍Policies 和Policy Classes。Policies 和Policy Classes有助于我们设计出安全且有效率,具有高度弹性的【设计元素】。所谓Policy,即用来定义一个class 或class template的介面,该介面由下列项目之一或全部组成:内隐型别定义,成员函式和成员变量。

Policies 也被其他人用于traits,不同的是后者比较重视行为而非型别,policies也让人联想到设计范式strategy,只不过policies吃紧于编译期(compile—time bound)。

举个例子,定义一个policy用来生成物件:creator policy是个带有型别T的class template,它必须提供一个名为create的函数给外界使用。这个函数不接受参数,传回一个 T的指针。就语义而言,每当create()被call就必须传回一个指标,指向新生的T物件,至于物件的精确生成模式,留给policy实作品来做订制因子。

现在定义一个可实作出creator policy的class。产生物件的可行办法总体有三种,一即为运算式new,另一种即为malloc加上placement new运算子。此外还可以采用复制的方式。以下为实现代码:

 

template
struct OpNewCreator
{
    static T* create()
    {
        return new T;
    }
};
template
struct MallocCreator
{
    static T* create()
    {
        void *buf=malloc(sizeof(T));
        return buf?new(buf) T:0;
    }
};
template
struct PrototypeCreator
{
    PrototypeCreator(T * pObj=0)
        :pPrototype_(pObj)
    { }
    T* create()
    {
        return pPrototype_?pPrototype_->Clone():0;
    }
    T *GetPrototype()
    {
        return pPrototype_;
    }
    void SetPrototype(T *pObj)
    {
        pPrototype_=pObj;
    }
private:
    T *pPrototype_;
};

 

 

任何一个policy 都可以有无限多的实作品。实作出的policy 即为policy classes ,或许这个名字不够精确,因为如你所见,policy 的实作品也可以是class template。然而,这东西并不是期望被单独使用,它们主要被用于继承或被内包含其他的classes。

这里有一个重要的概念:policies介面个一般的传统的classes 介面(纯虚函数 classes)不同,它结构比较松散,一位内polices是语法导向而非标记导向。换句话来说creator明确定义的是“怎样的语法构造符合其所规范的class” ,而非“必须实作出哪些函数”。例如creator policy 并没有规范create()必须是static还是virtual,它只是要是class 必须定义出create()。此外creator也只规定create()应该传回一个指向新物件的指针但不是必须的。因此create()也许会传回nullprt 或丢出异常,这些都极为可能。

面对一个policy ,你可以实作出数个policy classes 。它们全都必须遵守policy 所定义的介面。往后你会看到一个例子,使用者选择了一个policy 并应用到较大的结构当中。

先前定义的三个policy classes ,各有不同的实作方式,甚至连介面都不尽相同(第三个policy classes 多了两个函数)。尽管如此,它们全都定义了create(),并传回必要的返回型别。因此它们都符合creator policy。

以下展现的是如何设计一个class 得以利用creator policy,它以复合或继承的方式使用先前所定义的三个classes 之一:

 

template
class WidgetManaget:public T
{ ... };

 

 

如果class 采用一个或多个policies,我们称其为hosts 或host classes,虽然host classes从技术上来说是host class template,但是不论host classes或host calss template,都意味着相同的概念。上例的widgetmanager便是采用了一个policy 的host class。Hosts负责把policies提供的结构和行为组成一个更加复杂的结构和行为。

当客户端讲widgetmanager template具现化的时候,必须传进一个他所期望的policy:

 

typedef WidgetManaget> MyWidgetMgr;

 

 

让我们分析整个过程的来龙去脉,无论何时,当一个MyWidgetMgr物件需要产生一个widget物件,它便call 它的policy子物件opnewcreator所提供的create()。选择【生成策略】是widgetmanager使用者的权利。藉由这样的设计,可以让widgetmanager使用者自动装配他所需要的机能。这便是整个policy based class 的设计主旨。

如同先前的例子所示,policy 的template参数往往都是累赘。使用者每每需要传入template参数给opnewcreator,这很笨拙。一般来说host class 已经知道policy class 所需参数,或者能轻易地推到出来。上述例子中widgetmanager 总是操作widget物件。这样的情况下还要求使用者把widget型别传入opnewcreator,这就显得多余且沉坠。

这时候程式库可以使用 template template参数来描述policies,如下所示:

 

 

template  class T>
class WidgetManaget:public T
{ ... };

 

 

尽管定义了created参数,但其并未对widgetmanager 有任何贡献。你不能在widgetmanager仲使用created,它只是 T的形式参数,因此可以省略。

应用端现在只需要使用widgetmanager时提供template名称即可:

 

typedef WidgetManaget MyWidgetMgr;

 

 

搭配policy class 使用 template template参数,并不单纯为了方便简约。有时候这种用法不可或缺。以便host class 可藉由templates 产生不同型别的物件。举个例子,假设widgetmanager 想要以相同的生成策略产生一个Gadget物件,代码如下所示:

 

template


点击复制链接 与好友分享!回本站首页
上一篇:Mybatis调用PostgreSQL存储过程实现数组入参传递
下一篇:fpga的sdram通用读写软ip
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站