• 读书日记-策略模式


    开始之前

      每次看书都会收获不一样的感受,走过的弯路越多回头来看前人整理的书籍,才发现原来都在上面。

    框架写的越多,看起HeadFirst越能体会它的好。

    策略模式定义

      定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户

    设计原则

      1、找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

      2、针对接口编程,而不是针对实现编程。
      3、多用组合,少用继承。

    这是书上的Tips,前人总结的准则,在设计系统应该多加参考。

    案例

      在一个模拟鸭子游戏:SimUDuck。游戏中有各种鸭子,一边游泳戏水,一边呱呱叫。现在设计了一个Duck的类,并让各种鸭子继承此超类。

      

    问题:现在新增了一个需求,需要让MallardDuck和RedheadDuck有飞的方法,同时新增一个DecoyDuck(诱捕鸟)子类不要飞的方法。

    一般的做法:

      在Duck类里写一个Fly()方法,让子类继承。MuteDuck中覆盖去掉实现。但是,这是针对实现编程,且每多一个子类,便要多设置一次。

    策略模式实现的做法:

      在将fly方法提出来,单独写一个接口类如下:

    // 关于飞的接口类
    class IFlyBehavior
    {
        virtual void fly() =0 ;
    } 
    // 可以飞的实现 
    class FlyWithWings:public IFlyBehavior
    {
        virtual void fly() override{ printf("fly with  wings!");};
    }
    // 不能飞的实现 
    class NoWingsFly:public IFlyBehavior
    {
        virtual void fly() override{ printf("no fly!"); };
    } 

      这里方便显示直接将实现也写在头文件定义里,一般复杂的实现要单独在cpp中实现,这样才不会导致编译生成过大。

    在有了飞的方法类之后,我们只需要让Duck基类拥有IFlyBehavior对象,然后在新增的doFly()方法中调用即可。

    class Duck
    {
    public:
        void quack();
    
        void swim();
    
        void display();
    
        void doFly();
    protected:
        IFlyBehavior* m_pFlyBehavior;
    }
    void Duck::doFly()
    {
        if(m_pFlyBehavior)
        {
            m_pFlyBehavior->fly();
        }
    }

    然后再子类的构造函数中分别继承的IFlyBehavior对象进行不同的赋值。

    // 能飞的绿头鸭
    MallarDuck::MallarDuck(void)
    {
        m_pFlyBehavior = new FlyWithWings();
    }
    // 不能飞的橡胶鸭子
    DecoyDuck::DecoyDuck(void)
    {
        m_pFlyBehavior = new NoWingsFly();
    }

     这样的设计,可以让飞行这一行为被其他非鸭子类对象复用。同时可以再新增新的行为,也不影响鸭子类的飞行行为。

    结尾

      “有一个(拥有)” 可能比 “是一个”  更好。  这就是组合的好处了。

  • 相关阅读:
    gulp serve 报错 gulp.ps1
    执行git命令时出现fatal: 'origin' does not appear to be a git repository错误
    利用 SASS 简化 `nth-child` 样式的生成
    git的一些常用命令
    回调函数
    匿名函数
    css消除行内元素的间隙
    @click.native的使用
    Element-ui 下拉列表 选项过多时如何解决卡顿问题
    vue组件通信(父子之间,兄弟之间)
  • 原文地址:https://www.cnblogs.com/stratrail/p/5034231.html
Copyright © 2020-2023  润新知