设计模式之策略模式

上篇博文中,我们系统的学习了下工厂模式,下面我们就来学习下另一个设计模式——策略模式,策略模式的定义:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。对于策略模式,用户只需要关注所选择的策略,不必关注具体的策略实现,从而实现了接口和实现相分离,说了这么多,感觉还是很模糊,还是从代码上下手吧,代码如下:

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里面吧,好了,本篇博文到此结束,下篇博文我们将继续分析下一个设计模式——适配器模式,尽情期待,多谢了,

如果需要,请注明转载,多谢

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值