设计模式之策略模式
上篇博文中,我们系统的学习了下工厂模式,下面我们就来学习下另一个设计模式——策略模式,策略模式的定义:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。对于策略模式,用户只需要关注所选择的策略,不必关注具体的策略实现,从而实现了接口和实现相分离,说了这么多,感觉还是很模糊,还是从代码上下手吧,代码如下:
1)直接传递策略对象的方式
#ifndef __STRATEGY__H #define __STRATEGY__H #include <iostream> #include <boost/smart_ptr.hpp> using namespace std; using namespace boost; class goWork { public: virtual void work() = 0; }; class goWorkByBus : public goWork { public: void work() { cout<<"go work by bus"<<endl; } }; class goWorkByBike : public goWork { public: void work() { cout<<"go work by bike"<<endl; } }; class goWorkByFoot : public goWork { public: void work() { cout<<"go work by foot"<<endl; } }; class WorkByWay { public: WorkByWay(shared_ptr<goWork>& gowork):tool(gowork) { } void work() { tool->work(); } private: shared_ptr<goWork> tool; }; #endif include "Strategy.h" int main() { shared_ptr<goWork> gowork(new goWorkByBus()); WorkByWay workbyWay(gowork); workbyWay.work(); shared_ptr<goWork> gowork1(new goWorkByBike()); WorkByWay workbyWay1(gowork1); workbyWay1.work(); return 0; }
用这种方式最大的问题就是:直接暴露了类的实现方式,因此,在此基础上人们又想出了另外的解决方案,就通过向目标对象传递标志的方式,代码如下:
#ifndef __STRATEGY__H #define __STRATEGY__H #include <iostream> #include <boost/smart_ptr.hpp> using namespace std; using namespace boost; class goWork { public: virtual void work() = 0; }; class goWorkByBus : public goWork { public: void work() { cout<<"go work by bus"<<endl; } }; class goWorkByBike : public goWork { public: void work() { cout<<"go work by bike"<<endl; } }; class goWorkByFoot : public goWork { public: void work() { cout<<"go work by foot"<<endl; } }; enum WAY { BUS, BIKE, FOOT }; class WorkByWay { public: WorkByWay(WAY way) { switch(way) { case BUS: tool= shared_ptr<goWork>(new goWorkByBus()); break; case BIKE: tool= shared_ptr<goWork>(new goWorkByBike()); break; case FOOT: tool= shared_ptr<goWork>(new goWorkByFoot()); break; } } void work() { tool->work(); } private: shared_ptr<goWork> tool; }; #endif #include "Strategy.h" int main() { WorkByWay workByWay1(BUS); WorkByWay workByWay2(BIKE); WorkByWay workByWay3(FOOT); workByWay1.work(); workByWay2.work(); workByWay3.work(); return 0; }
从上述代码中可以看到,其主要是通过传递了一个标记给目标对象,这样克服了直接将传递对象带来的一些不安全问题,并且使得用户不用太关心接口的具体实现,从而提高了类的封装性,接下来,我们再来看看如果采用模板的方式来实现的话,该如何做,这种方法,来标记都省略了,但是需要用户指明其使用的是哪个算法类,代码如下:
3)模板方式
#ifndef __STRATEGY__H #define __STRATEGY__H #include <iostream> #include <boost/smart_ptr.hpp> using namespace std; using namespace boost; class goWork { public: virtual void work() = 0; }; class goWorkByBus : public goWork { public: void work() { cout<<"go work by bus"<<endl; } }; class goWorkByBike : public goWork { public: void work() { cout<<"go work by bike"<<endl; } }; class goWorkByFoot : public goWork { public: void work() { cout<<"go work by foot"<<endl; } }; template<class T> class WorkByWay { public: WorkByWay() { tool = shared_ptr<T>(new T()); } void work() { tool->work(); } private: shared_ptr<goWork> tool; }; #endif #include "Strategy.h" int main() { WorkByWay<goWorkByBus> workByWay1; WorkByWay<goWorkByBike> workByWay2; WorkByWay<goWorkByFoot> workByWay3; workByWay1.work(); workByWay2.work(); workByWay3.work(); return 0; }
其实模板方式还是很简单,只是最大的问题就是用户必须要指明算法的实现类名,这样也就等于暴露了相关类的实现,给用户带来了不必要的负担,所以个人还是比较喜欢第二种方式,因为在第二种方式中,其实它融合了工厂模式的设计思想。
总结
本篇博文主要是分析了设计模式中的策略模式,其实这种模式设计思想很简单,主要是根据根据不同的算法,实现相互之间的替换,上述的一些案例也是很简单的,其实要想用好策略模式,我们需要进行一些必要的练习,等有时间的话,自己也想写几个关于设计模式方面的应用案例,到时候在一起放在github里面吧,好了,本篇博文到此结束,下篇博文我们将继续分析下一个设计模式——适配器模式,尽情期待,多谢了,
如果需要,请注明转载,多谢
原文:http://blog.csdn.net/zmyer/article/details/19629093