设计模式——策略模式

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

内容简介:《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!

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

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


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

查看所有标签

猜你喜欢:

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

Inside Larry's and Sergey's Brain

Inside Larry's and Sergey's Brain

Richard Brandt / Portfolio / 17 Sep 2009 / USD 24.95

You’ve used their products. You’ve heard about their skyrocketing wealth and “don’t be evil” business motto. But how much do you really know about Google’s founders, Larry Page and Sergey Brin? Inside......一起来看看 《Inside Larry's and Sergey's Brain》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具