设计模式1:策略模式

来源:互联网 发布:安装软件 编辑:程序博客网 时间:2024/04/28 10:27

前言:

今天开始学习设计模式,课程设计需要,同时设计模式对程序猿真的很重要。强烈推荐Head First设计模式这本书,图片文字安排的很合理,阐述方式也比较容易被接受,所以让人有学下去的欲望。好啦,废话就这么多,开始做笔记。。

策略模式(Strategy Pattern)

应用背景:模拟鸭子,有一个鸭子超类Duck,两个鸭子子类MallardDuck和RedheadDuck。

超类Duck

public abstract class Duck {    public abstract void quack();    public abstract void swim();    public abstract void display();}

子类MallardDuck

public class MallardDuck extends Duck {    @Override    public void quack() {        // TODO Auto-generated method stub    }    @Override    public void swim() {        // TODO Auto-generated method stub    }    @Override    public void display() {        // TODO Auto-generated method stub        System.out.println("Green Head Duck");    }}

子类RedheadDuck

public class RedheadDuck extends Duck {    @Override    public void quack() {        // TODO Auto-generated method stub    }    @Override    public void swim() {        // TODO Auto-generated method stub    }    @Override    public void display() {        // TODO Auto-generated method stub        System.out.println("Red Head Duck");    }}

新需求:

如果要让鸭子飞起来,我们通常会在超类Duck里加一个fly()方法,让子类都去实现fly()方法

问题:

如果添加一个子类RubberDuck(橡皮鸭),橡皮鸭会继承Duck的fly()和quack()方法,这显然不合理(橡皮鸭不会飞也不会呱呱叫)。虽然可以在RubberDuck的fly()和quack()方法里改写,已覆盖超类的方法,但是如果以后加入更多的鸭子(不会飞,不会叫)子类,那么每个子类里面的fly(),quack()也都要改写;如果把fly()抽出来放进一个Flyable()接口,那么如果有很多个Duck的子类都要改一下fly的方法,重复的代码会非常多。
  • 设计原则1:找出应用中可能需要变化的部分,把它们独立出来,不要和那些不需要变化的代码混在一起(把会变化的部分取出来并封装起来,以便以后可以轻易的改动或者扩充此部分,而不影响不需要变化的其他部分)。

  • 设计原则2:针对接口编程,而不是针对实现编程(即针对超类型编程)

  • 设计原则3:多用组合,少用继承(HAS-A 可能比IS-A更好)

因此,重新设计类:
Duck类

package pattern.strategy;public abstract class Duck {    FlyBehavior flyBehavior;    QuackBehavior quackBehavior;    public Duck(){    }    public abstract void display();    public void performFly(){        flyBehavior.fly();    }    public void performQuack(){        quackBehavior.quack();    }    public void swim(){        System.out.println("All ducks swim");    }    public void setFlyBehavior(FlyBehavior flyBehavior) {        this.flyBehavior = flyBehavior;    }    public void setQuackBehavior(QuackBehavior quackBehavior) {        this.quackBehavior = quackBehavior;    }}

FlyBehavior接口

package pattern.strategy;public interface FlyBehavior {    public void fly();}QuackBehavior接口package pattern.strategy;public interface QuackBehavior {    public void quack();}

子类MallardDuck

package pattern.strategy;public class MallardDuck extends Duck {    public MallardDuck(){        quackBehavior = new Quack();        flyBehavior = new FlyWithWings();    }    @Override    public void display() {        // TODO Auto-generated method stub        System.out.println("I am a real Mallard Duck");    }}

子类ModelDuck

package pattern.strategy;public class ModelDuck extends Duck {    public ModelDuck(){        flyBehavior = new FlyNoWay();        quackBehavior = new Squeak();    }    @Override    public void display() {        // TODO Auto-generated method stub        System.out.println("I am a model duck");    }}

测试代码:

package pattern.strategy;public class Test {    public static void main(String[] args) {        Duck mallard = new MallardDuck();        mallard.performFly();        mallard.performQuack();        System.out.println();        Duck model = new ModelDuck();        model.performFly();        model.setFlyBehavior(new FlyRocketPower());        model.performFly();    }}

结果:

I am flying!I can quack!I cannot flyI can fly by a rocket
1 0