• 设计模式学习总结:(3)策略模式


    策略模式(strategy):

    属于行为模式

    意图:

    定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。本模式使得算法可独立于它的客户而变化。

    什么意思呢,我想的是,算法独立于客户,我们把一些算法具体实现封装起来,成为具体的类,而每一个算法独立为一种具体策略,把算法和环境(context)独立开来,这样有利于算法的扩展,很明显,这种模式很适合用于策略容易发生变化的业务。还是以具体的实例做基础吧。

    假设这样的业务,游乐场,我们针对不同的项目,计算不同的开销,其实我不了解具体开销是不是以算法的形式,但是我们假设每一种开销有一种固定算法。假设一开始,我们支持过山车,碰碰车,海盗船,最简单的实现是这样:

    enum GameType {
        Roller,   
        PoCar,
        PirateShip,
            //更改
    };
    class Economic:
    {
    private:
        GameType _g_Type;
    public:
        double caculateOut()
       {
            switch(_g_Type)
            {
                 case Roller:
                     //算法1
                     break;
                 case  PoCar:
                      //算法2
                      break;
                 case PirateShip:
                      //算法3
                      break;
             }
        }
    }    

    当然这样也是可以实现,但是这样不好,如果我们需要支持更多的项目,我们还要加多的枚举type,然后新增加一个case,比如自由落体项目,那还得修改代码。很明显违背了"开放封闭原则"。这样的例子是最好用策略模式的,首先,这里的确需要多种算法(策略),并且算法可能增加(变化)。运用策略模式,那么我们首先需要抽象一个策略基类。然后将算法从环境类(这里是Economic)里面分离出来,在策略基类中实现它们。

    所以,改成这样是不是好一点:

    定义抽象策略类。

    class TypeStrategy
    {
    public:
        virtual double calculate()=0;
        ~virtual TypeStrategy;
    }

     将已有业务算法实现:

    class RollerStrategy:public TypeStrategy
    {
    public:
        double calculate()
        {
             //具体实现
        }
    }
    class PocarStrategy:public TypeStrategy
    {
    public:
        double calculate()
        {
             //具体实现
        }
    }
    class PirateShipStrategy:public TypeStrategy
    {
    public:
        double calculate()
        {
             //具体实现
        }
    }

    定义算法的执行环境类:

    class Economic
    {
    private:
        TypeStrategy *_stgy;
    public:
        Economic(StrategyFactory* factory)
        {
            _stgy  = factory->setup(); 
        }
        ~Economic()
        {
            delete _stgy;
        }
    
         double calculateOut()
         {
             return _stgy->calculate();
          }
    }

    如果有必要,还得定义一个context对象来保证算法和类之间的数据。

    现在,我们假设需要增加一个项目,比如是鬼屋。

    我们只需要定义我们的算法即可,做如下改动:

    //扩展
    class ShriedStrategy:public TypeStrategy
    {
    public:
        double calculate()
        {
         //具体实现
        }
    }

    而不需要对别的地方进行改动。保证了"开放封闭原则"。

    书上给的策略模式结构图是这样的:

    可以看到实现context和strategy的分离,然后对strategy进行抽象。

  • 相关阅读:
    WinForm 自定义控件 学习笔记三
    FtpWebRequest相关
    delegate学习笔记1
    C#操作XML
    WinForm 非客户区相关
    WinForm 自定义控件 学习笔记二
    POJ1061 青蛙的约会(扩展欧几里得)
    aaaaaaa……aaa(n个)%p的值 (矩阵快速幂)
    POJ3735 Training little cats(矩阵快速幂)
    数据库日志文件太大的解决方法及原理
  • 原文地址:https://www.cnblogs.com/wuweixin/p/5421740.html
Copyright © 2020-2023  润新知