policy是规定好的 规章制度之类的一般是没有疑问要按照执行的 类似政府策略 或者公司的规章守则,strategy有点类似于计策 比如说我想开办一个公司的经营策略 营销策略之类的。今天我们讨论的是loki库中的policy,和设计模式中的strategy是要区别开来的。
Modern C++ Design的第一章就是Policy Based Class Design,可见该技术是整个Loki库的设计基础.这种方式的优点是能够增加程序库的弹性和提高复用性.
简单来说就是,一个Policy Based Class由很多基本的Policy来组成的,每个Policy Class代表了该复杂类(相对复杂)类的某些行为或者特性.有点类似于类的继承,当然和类的继承是不同的。
按照惯例,先谈需求。我需要完成一个自动更新程序。分四种情况。更新,更新列表,自动下载,主程序启动时安装。这四种情况非常相似,基本上包含或者部分包含以下几个函数。CheckDownLoad、InitDownload、ExecDownload、InitUpdate、ExecUpdate这种情况,更新:用户一点更新(CheckDownLoad、InitDownload、ExecDownload、InitUpdate、ExecUpdate),下载和更新一气呵成。更新列表(CheckDownLoad、InitDownload和CheckDownLoad、InitDownload、ExecDownload、InitUpdate、ExecUpdate)区别是更新列表需要先显示,用户点确定了,才能更新。自动下载(CuoFenControl、CheckDownLoad、InitDownload、IsNeedDown、ExecDownload、CCallBackTimerRun) 主程序启动是安装(OnlyInitDownload,InitUpdate,CCallBackFirstRun和InitUpdate)。
Policy是对付这个的最好方法。
1.UpdatePolicy.h
#ifndef UpdatePolicy_H
#define UpdatePolicy_H
#include "UpdateAuto.h"
#include "CommandEventMediator.h"
class CGetUpdateListCuoFeng
{
public:
static bool Excute();
};
class CGetUpdateList
{
public:
static bool Excute();
};
class CGetUpdateListNoDownload
{
public:
static bool Excute();
};
class CDownLoadNormal
{
public:
static bool Excute();
};
class CDownLoadTimer
{
public:
static bool Excute();
};
class CUpdateNormal
{
public:
static bool Excute();
};
class CInstallUpdate
{
public:
static bool Excute();
};
class CInstallCheck
{
public:
static bool Excute();
};
class CExcuteNothing
{
public:
static bool Excute()
{
return true;
}
};
class CCallBackNothing
{
public:
CCallBackNothing()
{
}
void operator ()(const bool _bSuccess)
{
}
};
template<class GetUpdateListPolicy = CGetUpdateList,class DownLoadPolicy = CDownLoadNormal,class UpdatePolicy = CUpdateNormal,class CCallBack = CCallBackNothing>
class CUpdateAutoRun
{
public:
typedef CUpdateAutoRun<GetUpdateListPolicy, DownLoadPolicy, UpdatePolicy,CCallBack> __thisClass;
static void ThreadRun()
{
_beginthread(&__thisClass::_Run, 0, 0);
}
static void _Run(void *p = NULL)
{
bool bRet = false;
TheUpdateAuto::Instance().SetRunning(true);
if (GetUpdateListPolicy::Excute() && DownLoadPolicy::Excute() && UpdatePolicy::Excute())
{
bRet = true;
}
CCallBack *pCallBack = new CCallBack();
(*pCallBack)(bRet);
delete pCallBack;
pCallBack = NULL;
TheCommandEventMediator::Instance().InvokeEvent(CCommandEventMediator::UPDATEEND);
TheUpdateAuto::Instance().SetRunning(false);
}
};
#endif /*UpdatePolicy_H*/
2.UpdatePolicy.cpp
#include "stdafx.h"
#include "UpdatePolicy.h"
...
bool CGetUpdateList::Excute()
{
return TheUpdateAuto::Instance().CheckDownLoad()
&& TheUpdateAuto::Instance().InitDownload();
}
bool CGetUpdateListNoDownload::Excute()
{
return TheUpdateAuto::Instance().InitDownload();
}
...
3.把这些类组合起来
typedef CUpdateAutoRun<CGetUpdateListCuoFeng,CDownLoadTimer,CExcuteNothing,CCallBackTimerRun> CUpdateCuoFen; typedef CUpdateAutoRun<CGetUpdateList,CDownLoadNormal,CUpdateNormal> CNoCuoFenUpdateNormal; typedef CUpdateAutoRun<CGetUpdateListNoDownload,CExcuteNothing,CInstallCheck,CCallBackFirstRun> CUpdateCheck; typedef CUpdateAutoRun<CExcuteNothing,CExcuteNothing,CInstallUpdate> CJustUpdate;
4.如此调用。
CNoCuoFenUpdateNormal::ThreadRun();
完毕。