C++ Programmer's Cookbook

{C++ 基础} {C++ 高级} {C#界面,C++核心算法} {设计模式} {C#基础}

策略模式(policy)


一,策略模式
   在看《C++设计新思维》的时候,发现在一开始就大篇幅的介绍策略模式(policy),策略模式不属于经典设计模式中的一种,但是其实在我们日常的开发中是必不可少的。policy,策略,方针,这里的意思是指把复杂功能的类尽量的拆分为功能单一的简单类的组合,简单的类只负责单纯行为或结构的某一方面。增加程序库的弹性,可复用性,可扩展性。policy是一个虚拟的概念,他定义了某一类class的一些接口规范,并不与C++语法的关键字对应,只是一个抽象的概念。

二  实例1

//policy模式的常见使用实例smartptr,
template
<
   
class T,
   template 
<class> class CheckingPolicy,
   template 
<class> class ThreadingModel
>
class SmartPtr
   : 
public CheckingPolicy<T>
   , 
public ThreadingModel<SmartPtr>
{   
   T
* operator->()
   
{
      typename ThreadingModel
<SmartPtr>::Lock guard(*this);
      CheckingPolicy
<T>::Check(pointee_);
      
return pointee_;
   }

private:
   T
* pointee_;
}
;

三  实例二,比如说:我们定义一个policy,他是一个带有参数T的一个模版,他必须有一个Create函数,且返回T类型指针。对于这个定义,我们可以有不同的实现,从而满足不同用户的不同的需求。

template <class T>
struct OpNewCreator
{
   
static T* Create()
   
{
      
return new T;
   }

}
;

template 
<class T>
struct MallocCreator
{
   
static T* Create()
   
{
      
void* buf = std::malloc(sizeof(T));
      
if (!buf) return 0;
      
return new(buf) T;
   }

}
;

template 
<class T>
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_;
}
;

//test class
class Widget
{
}
;

//调用方法一:
template <class CreationPolicy>
class WidgetManager : public CreationPolicy
{   
}
;
void main()
{

typedef WidgetManager
< OpNewCreator<Widget> > MyWidgetMgr;


}


//调用方法二:因为一般Manager是特定于某一类的class,所以在Manager中就指定要处理的class类型。
template <template <class Created> class CreationPolicy>
class WidgetManager : public CreationPolicy<Widget>
{   
}
;
void main()
{
    
// Application code
typedef WidgetManager<OpNewCreator> MyWidgetMgr;
}

对于上面一个策略有3中不同的实现,从而就可以满足不同的客户的需求。
但是对于上面的使用,我们还可以有更好的修改:因为Policy的实现class一般会被继承,所以我们要考虑他的析构,一般的我们使析构函数virtual,但是这里会影响template的静态编译特性,影响效率,所以我们使用protected或private的析构函数,既不影响继承类对基类的析构,也不影响使用。
如修改如下:
template <class T>
struct OpNewCreator
{
   
static T* Create()
   
{
    
return new T;
   }

protected:
   
~OpNewCreator() {}
}
;

我们还可以修改上面的manger,实现creator policy的switch:
template <template <class> class CreationPolicy>
class WidgetManager : public CreationPolicy<Widget>

   
void SwitchPrototype(Widget* pNewPrototype)
   
{
      CreationPolicy
<Widget>& myPolicy = *this;
      delete myPolicy.GetPrototype();
      myPolicy.SetPrototype(pNewPrototype);
   }

}
;


四 policy 模式对我们创建可复用,可扩展的库的开发有非常重要的作用,是OO的基本的设原则式之一。

posted on 2007-05-24 19:42 梦在天涯 阅读(4871) 评论(2)  编辑 收藏 引用 所属分类: CPlusPlusDesign pattern

评论

# re: 策略模式(policy) 2009-02-13 00:58 林海枫

可以把WidgetManager 接口变得更通用点吗?下面这样可以吗?

template <class T, template <class Created> class CreationPolicy>
class Manager : public CreationPolicy<T>
{
};

这样就可以如下使用了:

Widget *widget = Manager<T, OpNewCreator>::create().

细节问题没有认真查看,不知上述代码对否,呵呵!  回复  更多评论   

# re: 策略模式(policy) 2009-02-19 18:24 hah

楼上的那么做是可以的,但是你的写法不对
template <class T, template <class > class CreationPolicy>
class Manager : public CreationPolicy<T>
{
};

typedef Manager<widget, OpNewCreator> MyWidgetMgr;
MyWidgetMgr myMgr;
Widget *widget = myMgr.Create();  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

EMail:itech001#126.com

导航

统计

  • 随笔 - 461
  • 文章 - 4
  • 评论 - 746
  • 引用 - 0

常用链接

随笔分类

随笔档案

收藏夹

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

积分与排名

  • 积分 - 1795671
  • 排名 - 5

最新评论

阅读排行榜