策略模式

目录

经典的鸭子问题

策略模式的UML图

策略模式解决鸭子问题

什么是策略模式

策略模式在Arrays工具类中的应用

用策略模式来替代if-else

使用策略模式的注意事项 


 

经典的鸭子问题

 

 

我们先通过一个例子来逐步分析,为什么要使用“策略模式”解决鸭子问题。

现在有各种鸭子(比如野鸭、北京鸭、水鸭等,而鸭子有各种行为,例如叫和飞行),各种鸭子的行为是不一样的,如野鸭会飞,水鸭不会飞。怎么用程序实现各种鸭子的代码呢?

传统的方案是这样的。定义一个抽象类Duck,具体的鸭子继承这个Duck类,不同的鸭子类重写Duck类中的行为方法。


使用继承,子类重写父类有什么问题呢?

如果所有鸭子都继承了fly,代表所有鸭子都会飞,不会飞的鸭子,你这么写就很不合适。相当于new一个不会飞和叫的鸭子时,要先继承飞和叫接口,然后手动重写,让鸭子不会飞也不会叫~

 

 

策略模式的UML图

 

完全不用解释图中的各个元素代表什么意思,因为在下面的实战中,我们会把上面的实体名都替换成鸭子的相关名称~ 

 

 

策略模式解决鸭子问题

 

我们来“对号入座”。策略模式是把继承的强耦合给打散,祖宗类(接口)还是Duck。Duck下面有两个方法,飞和叫。但这两个方法中并没有写任何具体的实现!

我们把叫和飞两个方法单独抽离出来作为接口,我们让每种“叫声”单独作为一个类,每种“飞”的熟练度也单独作为一个类。这些具体的类继承于飞和叫两个接口,这两个接口又和Duck类是“组合/聚合关系"
接下来就有趣了,假如你要一个野鸭,它飞的贼6、叫的贼好该怎么搞呢?

 

飞接口 

public interface FlyBehavior{
    void fly();
}

 飞接口的具体实现类:“飞的6类”、剩下的“不会飞类”、“飞的不咋地类”省略。

public class GoodFlyBechavior implements FlyBehavior {
    @Override
    public void fly(){
        System.out.println("飞的贼6");
    }
}

 然后新建Duck类,Duck类中聚合了飞和叫两个接口,飞和叫各有一个方法,意思是只有你传入了fly或quack,才会使用你传入的fly或quack,否则默认不飞也不叫~

public abstract class Duck {
    FlyBehavior flyBehavior;  //飞接口
    QuackBehavior quackBehavior;    //叫接口

    public Duck(){

    }

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

    public void quack(){
        if(quackBechavior != null) {
            quackBehavior.quack();
        }
    }

    public void fly(){
        if(flyBechavior != null) {
            flyBehavior.fly();
        }
    }

    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

    public void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }
}

接下来我们新建野鸭类,北京鸭和玩具鸭相似这里省略

public class WildDuck extends Duck {
    //构造器 我们new的是实现类
    public WildDuck() {
        flyBehavior = new GoodFlyBehavior();
    }

    @Override
    public void display() {
        System.out.println("这是野鸭");
    }
}

最后我们来建立Client类,调用需要的鸭子

public class Client {
    psvm(){
        WildDuck wildDuck = new WildDuck();
        wildDuck.fly();
    }
}

通过client类我们可以发现,我们new了WildDuck后 ,实际上是用了封装在WildDuck类中的行为和方法。以后如果你需要让野鸭变得不会飞,找到WildDuck类,改成new NoFlyBehavior方法即可,其他完全不用动。我们成功做到了让变与不变相分离

这不算最妙的,最妙的是你可以在client类中动态的改变“野鸭的行为”。

经过下面的修改后,野鸭子不会叫了~

public class Client {
    psvm(){
        WildDuck wildDuck = new WildDuck();
        wildDuck.setFlyBehavior(new NoFlyBehavior());
        wildDuck.fly();
    }
}

 

 

什么是策略模式

 

策略模式中定义了算法族(策略组),把变的部分和不变的部分拆分开,让算法的变化独立与使用算法的客户

策略模式体现了几个原则:针对接口编程、变与不变相分离、多用组合/聚合少用继承。 

 

 

策略模式在Arrays工具类中的应用

 

 

还记得我们在java基础中学过的比较方法Comparator吗?

看看下面的代码,我们知道默认使用arrays.sort方法时是升序排列数组。那如何降序呢?jdk提供的方法是重写Comparator接口,默认是o1-o2,你要改成o2-o1


public class Testexample {
    	   public static void main(String[] args) {
    		           /*注意,要想改变默认的排列顺序,不能使用基本类型(int,double, char)
    		           而要使用它们对应的类*/
    		           Integer[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
    		           //定义一个自定义类MyComparator的对象
    		           Comparator cmp = new MyComparator();
    		           Arrays.sort(a,cmp);
    		           for(int arr:a) {
    		               System.out.print(arr + " ");
    		           }
    		       }
    		   }
    		   //实现Comparator接口
    		   class MyComparator implements Comparator<Integer>{
    		      @Override
    		       public int compare(Integer o1, Integer o2) {
    		        /*如果o1小于o2,我们就返回正值,如果o1大于o2我们就返回负值,
    		         这样颠倒一下,就可以实现降序排序了,反之即可自定义升序排序了*/
    		       return o2-o1;    
       }
    	
  }

为什么o1和o2顺序颠倒后,排列的升降也颠倒了呢?因为Comparator方法就使用了策略模式,算法的变化影响返回给客户的结果

 

 

用策略模式来替代if-else

 

这里拆分变与不变的部分我们就不做展示了,这里想说明的是,策略模式通过创建对象的方式代替了if-else

完整版欢迎阅读https://www.cnblogs.com/geekdc/p/11580219.html

 

 

 

使用策略模式的注意事项 

 

1.策略模式的关键是分析项目中变化部分与不变部分

2.策略模式的核心是多用组合/聚合,少用继承

3需要注意没增加一个策略(算法),就要增加一个类。当策略过多时会导致类的数量庞大

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值