尚硅谷设计模式学习(23)---[策略模式(strategy pattern)]

尚硅谷传送门==>B站尚硅谷Java设计模式

❤❤❤感谢尚硅谷❤❤❤

最近开始计划学习一下设计模式了,加油!!!



情景引入

关于鸭子的问题

鸭子有各种种类= =>比如 野鸭、北京鸭、水鸭,玩具鸭,冲鸭;…
鸭子有各种行为动作,比如跑步,飞行…

传统方式解决问题

在这里插入图片描述

鸭子抽象类Duck

//鸭子类;
public abstract class Duck {
    public Duck() {

    }
    //鸭子的信息;
    public abstract void show();

    //鸭子说话;
    public void talk(){
        System.out.println("鸭子说话");
    };
    //鸭子跑步;
    public void run(){
        System.out.println("鸭子跑步");
    };
    //鸭子飞行;
    public  void fly(){
        System.out.println("鸭子飞啊飞");
    }
}

玩具鸭ToyDuck

//玩具鸭;
public class ToyDuck extends Duck{


    @Override
    public void show() {
        System.out.println("这是一只玩具鸭,可惜他不会飞,不会跑");
    }

    @Override
    public void run() {
        System.out.println("玩具鸭不会跑");
    }

    @Override
    public void fly() {
        System.out.println("玩具鸭不会飞");
    }
}

水鸭子WaterDuck

//水鸭子;
public class WaterDuck extends Duck {

    @Override
    public void show() {
        System.out.println("这是一只水鸭,他不会飞");
    }

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

野鸭WildDuck

//野鸭;
public class WildDuck extends Duck{
    @Override
    public void show() {
        System.out.println("这是一只野鸭,它会飞,会跑,会说话.");
    }
}

模拟客户端Client

//模拟客户端;
public class Client {
    public static void main(String[] args) {
        Duck duck = new ToyDuck();
        duck.show();
        duck.talk();
        duck.run();
        duck.fly();
    }
}
/*
这是一只玩具鸭,可惜他不会飞,不会跑
鸭子说话
玩具鸭不会跑
玩具鸭不会飞
*/

注意到一个问题,若按照这样的传统的方式设计这个问题,由于不同种类的鸭子可能行为方式不同,底部实现就要更改.
要是上层的鸭子抽象类中添加别的属性,下级鸭子可能还要去更改.


策略模式

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

原理图

在这里插入图片描述

(1)把原来变化的代码从不变的代码中分离出来;
(2)定义的是策略接口,即针对接口编程.
(3)尽量不要用继承;而是更改为组合或聚合.
(4)符合开闭原则


继续回到刚开始的鸭子分类以及行为的问题;用策略模式解决问题

在这里插入图片描述

在这里插入图片描述

说话策略接口TalkStrategy

/**
 * @author by CSDN@小智RE0
 */
//说话的行为策略接口;
public interface TalkStrategy {
    void talk();
}

跑步的策略接口RunStrategy

/**
 * @author by CSDN@小智RE0
 */

//跑步的行为接口;
public interface RunStrategy {
    void run();
}

飞行的策略接口FlyStrategy

/**
 * @author by CSDN@小智RE0
 */

//飞行的行为策略;
public interface FlyStrategy {
    void fly();
}

可以说话的策略实现ICanTalk

/**
 * @author by CSDN@小智RE0
 */

//可以说话的策略具体实现;
public class ICanTalk implements TalkStrategy{
    @Override
    public void talk() {
        System.out.println("可以说话");
    }
}

不可以说话的策略实现DoNotTalk

/**
 * @author by CSDN@小智RE0
 */

//不可以说话的策略具体实现;
public class DoNotTalk implements TalkStrategy{
    @Override
    public void talk() {
        System.out.println("不会说话");
    }
}

可以跑步的策略实现ICanRun

/**
 * @author by CSDN@小智RE0
 */
//可以跑步的策略具体实现;
public class ICanRun implements RunStrategy{
    @Override
    public void run() {
        System.out.println("可以跑步");
    }
}

不可以跑步的策略实现DoNotRun

/**
 * @author by CSDN@小智RE0
 */

//不可以跑步的策略具体实现;
public class DoNotRun implements RunStrategy{
    @Override
    public void run() {
        System.out.println("不会跑步");
    }
}

可以飞行的策略实现ICanFly

/**
 * @author by CSDN@小智RE0
 */

//可以飞行的策略具体实现;
public class ICanFly implements FlyStrategy{
    @Override
    public void fly() {
        System.out.println("可以飞行");
    }
}

不可以飞行的策略实现DoNotFly

/**
 * @author by CSDN@小智RE0
 */
//不可以飞行的策略具体实现;
public class DoNotFly implements FlyStrategy{
    @Override
    public void fly() {
        System.out.println("不能飞行");
    }
}

鸭子上层抽象类Duck

/**
 * @author by CSDN@小智RE0
 */
//鸭子类;
public abstract class Duck {
    //聚合飞行行为的策略接口;
    FlyStrategy flyStrategy;
    //聚合跑步行为的策略接口;
    RunStrategy runStrategy;
    //聚合说话行为的策略接口;
    TalkStrategy talkStrategy;

    //鸭子的信息显示;
    public abstract void show();

    //鸭子说话方法;
    public void talk(){
        if(talkStrategy!=null){
            talkStrategy.talk();
        }
    };
    //鸭子跑步方法;
    public void run(){
        if(runStrategy!=null){
            runStrategy.run();
        }
    };
    //鸭子飞行方法;
    public  void fly(){
       if(flyStrategy!=null){
           flyStrategy.fly();
       }
    }

    //改变飞行的策略实现;
    public void setFlyStrategy(FlyStrategy flyStrategy) {
        this.flyStrategy = flyStrategy;
    }

    //改变跑步的策略实现;
    public void setRunStrategy(RunStrategy runStrategy) {
        this.runStrategy = runStrategy;
    }

    //改变说话的策略实现;
    public void setTalkStrategy(TalkStrategy talkStrategy) {
        this.talkStrategy = talkStrategy;
    }
}

野鸭类WildDuck

/**
 * @author by CSDN@小智RE0
 */

//野鸭;
public class WildDuck extends Duck {
    //初始化;
    public WildDuck() {
        show();
        talkStrategy = new ICanTalk();
        runStrategy = new ICanRun();
        flyStrategy = new ICanFly();
    }

    @Override
    public void show() {
        System.out.println("这是一只野鸭,它会飞,会跑,会说话.");
    }
}

水鸭类WaterDuck

/**
 * @author by CSDN@小智RE0
 */

//水鸭子;
public class WaterDuck extends Duck {
    //初始化;
    public WaterDuck() {
        show();
        talkStrategy = new ICanTalk();
        runStrategy  = new ICanRun();
        flyStrategy  = new DoNotFly();
    }

    @Override
    public void show() {
        System.out.println("这是一只水鸭,他不会飞");
    }
}

玩具鸭类ToyDuck

/**
 * @author by CSDN@小智RE0
 */
//玩具鸭;
public class ToyDuck extends Duck {
    //初始化;
    public ToyDuck() {
        show();
        talkStrategy = new ICanTalk();
        runStrategy  = new DoNotRun();
        flyStrategy  = new DoNotFly();
    }

    @Override
    public void show() {
        System.out.println("这是一只玩具鸭,可惜他不会飞,不会跑");
    }
}

模拟客户端调用;

/**
 * @author by CSDN@小智RE0
 */
//模拟客户端;
public class Client {
    public static void main(String[] args) {
        Duck toyDuck = new ToyDuck();
        toyDuck.talk();
        toyDuck.run();
        toyDuck.fly();

        System.out.println("修改一下玩具鸭的跑步属性");
        toyDuck.setRunStrategy(new ICanRun());
        toyDuck.run();
    }
}
/*
这是一只玩具鸭,可惜他不会飞,不会跑
可以说话
不会跑步
不能飞行
修改一下玩具鸭的跑步属性
可以跑步
*/

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小智RE0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值