java设计模式学习之策略模式(更简单的理解设计模式)

OO角度

1、从项目"模拟鸭子游戏"开始

2、从OO的角度设计这个项目,鸭子超类,扩展超类:

Duck

/**
 * 以OO的角度设置这个项目。鸭子超类,拓展超类
 */
public abstract class Duck {
    public Duck() {
    }
    // 原本的需求 默认所有鸭子都会叫 都会游泳
    public void quack(){
        System.out.println("--gaga--");
    }
    public void swim(){
        System.out.println("--im swim--");
    }
    public abstract void display();

    // 新需求 鸭子有飞的功能
    // 这样修改让所有鸭子都会飞了。但是有一些鸭子是不会飞的
    // 继承的问题:对类的局部改动,尤其超类的局部改动,会影响其他部分。影响会有溢出效
    public void fly(){
        System.out.println("--fly--");
    }

}

子类

public class GreenHeadDuck extends Duck {
    @Override
    public void display() {
        System.out.println("--GreenHead--");
    }

    // 可以使用OO原理进行替换,将不会飞的鸭子的方法重写
    @Override
    public void fly() {
        System.out.println("GreemHeadDuck No fly!");
    }
}

public class RedHeadDuck extends Duck {
    @Override
    public void display() {
        System.out.println("--ReadHead--");
    }
}

Demo

public class Demo {

    public static void main(String[] args) {
        Duck greenHeadDuck = new GreenHeadDuck();
        greenHeadDuck.display();
        greenHeadDuck.quack();
        greenHeadDuck.swim();
        System.out.println("=======");

        Duck redHeadDuck = new RedHeadDuck();
        redHeadDuck.display();
        redHeadDuck.quack();
        redHeadDuck.swim();
        System.out.println("=======");

        // 新需求测试
        greenHeadDuck.fly();
        redHeadDuck.fly();

        /*
        extend带来的弊端:
            超类挖的一个坑,每个子类都要来填,增加工作量,复杂度O(N*N),不是好的设计方式
         */
    }
}

使用策略模式解决上述问题

需要新的设计方式,应对项目的扩展性,降低复杂度:
1)分析项目变化与不变部分,提取变化部分,抽象成接口+实现;
2)鸭子哪些功能是会根据新需求变化的?叫声、飞行…

Duck

/**
 * 用策略模式来新需求解决
 */
public abstract class Duck {
    /**
     *  分析项目变化部分与不变部分 提取变化部分 抽象成接口+实现
     *  将鸭子飞行、鸭子叫声抽像为接口+实现
     */
    FlyBehavior mFlyBehavior;
    QuackBehavior mQuackBehavior;
    // 新增鸭子游泳方式
    SwimBehavior mSwimBehavior;

    public Duck() {
    }
    public abstract void display();

    public void fly(){
        mFlyBehavior.fly();
    }

    public void quack(){
        mQuackBehavior.quack();
    }

    /**
     *  因为并不是抽象方法,所以不会强制要求所有的子类进行选择游泳方式
     *  只需要在需要描述游泳方式的子类构造方法中进行组合即可
     */
    public void swim(){
        mSwimBehavior.swim();
    }
}

子类

public class GreenHeadDuck extends Duck {

    /**
     * 构造方法中确定绿头鸭的行为
     */
    public GreenHeadDuck() {
        mFlyBehavior = new GoodFlyBehavior();
        mQuackBehavior = new GaGaQuackBehavior();
    }

    @Override
    public void display() {
        System.out.println("--GreenHead--");
    }


}

public class RedHeadDuck extends Duck {

    /**
     * 构造方法中确定红头鸭的行为
     */
    public RedHeadDuck() {
        mFlyBehavior = new GoodFlyBehavior();
        mQuackBehavior = new GeGeQuackBehavior();
    }

    @Override
    public void display() {
        System.out.println("--RedHead--");
    }


}

public class YellowHeadDuck extends Duck {

    /**
     * 构造方法中确定黄头鸭的行为 新增的黄头鸭会进行花式游泳
     */
    public YellowHeadDuck() {
        mFlyBehavior = new BadFlyBehavior();
        mQuackBehavior = new GeGeQuackBehavior();
        mSwimBehavior = new BackstrokeSwim();
    }

    @Override
    public void display() {
        System.out.println("--YellowHead--");
    }


}

接口及实现

public interface SwimBehavior {
    void swim();
}

public class BreaststrokeSwim implements SwimBehavior{

    @Override
    public void swim() {
        System.out.println("--BreaststrokeSwim--");
    }
}
public class BackstrokeSwim implements SwimBehavior{

    @Override
    public void swim() {
        System.out.println("--BackstrokeSwim--");
    }
}

public interface QuackBehavior {
    void quack();
}
public class GeGeQuackBehavior implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("--GeGe-- ");
    }
}
public class GaGaQuackBehavior implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("--GaGa-- ");
    }
}

public interface FlyBehavior {
    void fly();
}
public class BadFlyBehavior implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("Bad Fly!");
    }
}
public class GoodFlyBehavior implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("Good Fly!");
    }
}

Demo

public class Demo {

    public static void main(String[] args) {
        Duck greenHeadDuck = new GreenHeadDuck();
        greenHeadDuck.display();
        greenHeadDuck.fly();
        greenHeadDuck.quack();
        System.out.println("=======");

        Duck redHeadDuck = new RedHeadDuck();
        redHeadDuck.display();
        redHeadDuck.fly();
        redHeadDuck.quack();
        System.out.println("=======");

        // 新需求测试
        // 来了新鸭子 有不同的行为方式,只需要在构造方法中进行不同的组合即可
        YellowHeadDuck yellowHeadDuck = new YellowHeadDuck();
        yellowHeadDuck.display();
        yellowHeadDuck.fly();
        yellowHeadDuck.quack();
        // 新鸭子会仰泳
        yellowHeadDuck.swim();

    

策略模式总结:

/**
     *  策略模式: 分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。
     *  原则就是:分离变化部分:封装接口,基于接口编程各种功能。此模式让行为算法的变化独立于算法的使用者
     */

你可能感兴趣的:(设计模式)