设计模式——策略模式

栏目: 后端 · 发布时间: 5年前

内容简介:《Head First设计模式》笔记整理...欢迎交流...定义了算法簇,分别封装起来,让他们之间可以这里稍微提醒一下,策略模式是我们学习的第一个模式,理解它还是非常重要的。这个模式跟后面讲到的

《Head First设计模式》笔记整理...欢迎交流...

定义

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

这里稍微提醒一下,策略模式是我们学习的第一个模式,理解它还是非常重要的。这个模式跟后面讲到的 模板模式 有些相似的地方,我在学习的时候,看到模板模式已经忘记什么是策略模式了,看的一脸懵逼。不过没关系,后面我会针对这两个进行整理,这里要记住的是,策略模式封装了一组可以 互换 的算法簇,是 针对接口编程 的。

OO原则

  • 封装变化
  • 多用组合,少用继承
  • 针对接口编程,而不是针对实现编程

封装变化

为什么要封装变化?先来看下面的例子。

dock类是所有鸭子的超类,其中,飞行(fly)行为和呱呱叫(quack)行为会随着鸭子的不同而改变。如果我们不区分变化,将所有的行为定义在超类里。如图:

设计模式——策略模式

显而易见的,这种设计会导致

  • 改变牵一发而动全身
  • 不利于复用,不利于维护
  • 代码在多个子类中重复
  • 很难知道鸭子的全部行为
  • 运行时代码不容易改变

为了便于以后可以轻易地改动和扩展此部分,而不会影响不需要改变的其它部分,我们把变化的部分取出并封装起来。

设计模式——策略模式

使用继承如何?设计一个flyable接口和一个quackable接口。

设计模式——策略模式

哇,一堆重复的代码,而且代码难以复用。甚至在会飞的鸭子中,飞行的动作也可能是千变万化的。如果我们想要更加弹性一点, 在运行时也可以动态地选择行为 ,该怎么办呢?

针对接口编程

针对接口编程,而不是针对实现编程。这里所谓的“接口”有多个含义,接口可以是一个“概念”。”针对接口变成“,关键就在于 “多态” ,可以更明确地说, 变量的声明类型应该是超类型 。这也意味着,声明类是不必理会以后执行时的真正的对象类型。

设计模式——策略模式

如此,鸭子的行为被放在分开的类中,此类专门提供行为的接口实现。

这样,鸭子类就不再需要知道行为的实现细节。

多用组合,少用继承

当你讲两个类结合起来使用,就是组合。如图本列,将飞行行为和呱呱叫行为委托给FlyBehavior和QuackBehavior代为处理。组合建立系统有很大的弹性,不仅可将算法簇封装成类,更可以在运行时动态地改变行为,只要组合的行为对象符合正确的接口即可。

代码演示

publick abstract class Duck {
    //为行为接口类型声明两个引用变量,所有鸭子子类都继承它们
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;
    public Duck() {
    }
    
    publick abstract void display();
    
    public void performFly() {
        flyBehavior.fly(); //委托行为给类
    }
    
    public void performQuack() {
        quackBehavior.quack(); //委托行为给类
    }
    
    public viod  setFlyBehavior(FlyBehavior fb) {
        flyBehavior = fb; //动态设定飞行行为
    }
    
    public viod  setQuackBehavior(QuackBehavior qb) {
        quackBehavior = qb; //动态设定呱呱叫行为
    }
}

-----------------------------------------------------------

public interface FlyBehavior {
    public void fly();
}

public class FlyWithWings implements FlyBehavior {
    public viod fly() {
        System.out.printIn("I'm flying!");
    }
}

public class FlyNoWay implements FlyBehavior {
    public void fly {
        System.out.printIn("I can't fly!");
    }
}

-----------------------------------------------------------

public class QuackBehavior {
    public void quack();
}

public class Quack implements QuackBehavior {
    public void quack() {
        //此处省略
    }
}

public class MuteQuack implements QuackBehavior {
    public void quack() {
        //此处省略
    }
}

public class Squack implements QuackBehavior {
    public void quack() {
        //此处省略
    }
}
//制造一个新的鸭子类型:模型鸭

public class ModelDuck extends Duck {
    public ModelDuck() {
        flyBehavior = new FlyNoWay();
        quackBehavior = new Quack();
    }
    
    public viod display () {
        System.out.printIn("I'm a model duck");
    }
    
}

--------------------------------------------------------
//新建一个新的FlyBehavior类型

public class FlyRocketPowered implements FlyBehavior{
    public viod fly() {
        System.out.printIn("I'm flying with a rocket!");
    }
}

最后,来看看一个简单的测试

Duck model = new ModelDuck();
model.performFly(); // i can't fly!
model.setFlyBehavior(new FlyRocketPowered()); //动态改变行为
model.performFly(); // I'm flying with a rocket!

如果我们不再把鸭子的行为看做“一组行为”,而是想成是“一簇算法”,将这些算法抽离并封装起来,委托给对象,通过组合实现运行时算法互换,这就是策略模式。

好了,你觉得我的整理如何呢?如果有什么理解不对的地方,或者你有更好的想法欢迎交流。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

新榜样

新榜样

新榜 编著 / 电子工业出版社 / 2016-1 / 50.00元

本书为“新榜”全新打造的新媒体运营实战指南,全书基于对当前各类公众号的对比分析,阐述互联网时代各类公众号运营之道。全书分为五个部分,分别为:如何让政务公众号接地气,如何让自媒体公众号重获新生,如何做垂直领域的特色公众号,新媒体深度人物,以及新媒体深度分析等。一起来看看 《新榜样》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具