带你领略设计模式的魅力

一、策略模式——经典的“鸭子”行为问题

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

涉及设计原则

  1. 针对接口编程,而不是针对实现编程
  2. 找代码中变化的地方并把他们独立出来与不变的代码区分开

核心:运用类的多态性 实现了超类引用对其所有子类的管理(向上转型) 而子类的动作则是专门有行为接口去规定 子类的具体行为由动作接口实现去描述 最后超类和接口进行"组合" 实现了各个子类动作的真正区分

下面图片 均来自headfirst 设计模式一书 源码自己写的

鸭子游戏问题:
模拟鸭子活动,有各种鸭子 会游泳、会飞、会叫
图解:
在这里插入图片描述
选择鸭子作为一个超类 所有的鸭子都必须继承它
在这里插入图片描述
但是这样会导致各种各样的问题

  1. 有的鸭子不会飞
  2. 有的鸭子不会叫
    所以我们不能一味的继承 而是需要另一种方法 去实现
    在这里插入图片描述
    从上面我们知道了 鸭子都能游泳 但是有的鸭子却不会叫,有的鸭子能飞!所以我们需要在鸭子的超类上保留游泳动作,而会叫和能飞这两个动作就被提取出去了 但是接下来又该怎么办呢?
    在这里插入图片描述
    解决:
    将超类的飞 和叫 两个动作提取出去 当做接口使用 面向接口化编程 即把 fly 和 quack 不确定的方法抽取出去 封装在 一个飞动作接口 和 叫动作接口 下面是具体实现
    在这里插入图片描述
    整合鸭子的行为 所有的动作接口变量都在超类duck中 由超类控制公共方法 实现类某个方法实现接口变量 下面是具体做法
    在这里插入图片描述
    在这里插入图片描述

具体代码:
在这里插入图片描述

 * @description  超类
 **/
public abstract class Duck  {

    public FlyBehavior flyBehavior;

     public QuckBehavior quckBehavior;

    public void quck(){
          quckBehavior.quck();
    }

    public void fly(){
          flyBehavior.fly();
    }
    public void swimming(){
        System.out.println("鸭子都会游泳!");
    }

}

"飞"行为接口

public interface FlyBehavior {
    /**
     * 飞
     */
    void fly();
}

"叫"行为接口

public interface QuckBehavior {
    /**
     * 叫
     */
    void quck();
}

会飞鸭子动作具体实现

public class CanFlyImpl implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("这只鸭子会飞");
    }
}

会叫鸭子动作具体实现

public class CanQuckImpl implements QuckBehavior {

    @Override
    public void quck() {
        System.out.println("这只鸭子会叫");
    }
}

不会飞鸭子动作具体实现

public class NoWayFlyImpl implements FlyBehavior {


    @Override
    public void fly() {
        System.out.println("这只鸭子不会飞");
    }
}

不会叫鸭子动作具体实现

public class NoWayQuckImpl implements QuckBehavior {


    @Override
    public void quck() {
        System.out.println("这只鸭子不会叫");
    }
}

会飞的鸭子实体类

 * @description  会飞的鸭子
 **/ 
public class CanFlyDuck extends Duck  {

    public CanFlyDuck() {
        //具体实现动作接口
        this.flyBehavior = new CanFlyImpl();
        this.quckBehavior = new NoWayQuckImpl();
    }

    public void display(){
        System.out.println("会飞的鸭子却不会叫");
    }
}

会叫的鸭子实体类

 * @description 会叫的鸭子
 **/
public class CanQuckDuck extends Duck {


    public CanQuckDuck() {
    //具体实现动作接口
        this.flyBehavior = new CanFlyImpl();
        this.quckBehavior = new NoWayQuckImpl();
    }

    public void display(){
        System.out.println("会飞的鸭子却不会叫");
    }
}

测试:

/**
 * 策略模式
 */
Duck duck = new CanFlyDuck();
((CanFlyDuck) duck).display();
duck.fly();
duck.quck();
Duck duck1 = new CanQuckDuck();
((CanQuckDuck) duck1).display();
duck1.quck();
duck1.fly();
发布了47 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42083036/article/details/103277735
今日推荐