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*/
#include "stdafx.h" #include "UpdatePolicy.h" ... bool CGetUpdateList::Excute() { return TheUpdateAuto::Instance().CheckDownLoad() && TheUpdateAuto::Instance().InitDownload(); } bool CGetUpdateListNoDownload::Excute() { return TheUpdateAuto::Instance().InitDownload(); } ...
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();
完毕。