一起来了解Java的策略模式

 更新时间:2022年3月17日 16:58  点击:252 作者:热爱飞行的小应学长

策略模式

策略模式属于Java 23种设计模式中行为模式之一,那先看看什么是策略模式。

1、什么是策略模式

策略模式的定义:

该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

其实我们在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况,例如,出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等。或者比如网购,你可以选择工商银行、农业银行、建设银行等等,但是它们提供的算法都是一致的,就是帮你付款。

在软件开发中也会遇到相似的情况,当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。(这个在下面案例中详讲)

图解:

在这里插入图片描述

2、策略模式的优缺点

优点:

  • 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句
  • 提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码
  • 提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的
  • 提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法把算法
  • 的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离

缺点:

  • 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类
  • 策略模式造成很多的策略类,增加维护难度

3、策略模式的结构

1.抽象策略类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。

2.具体策略类:实现了抽象策略定义的接口,提供具体的算法实现。

3.环境类:持有一个策略类的引用,最终给客户端调用。

结构图:

在这里插入图片描述

4、代码实现

现在有三只鸭子: 绿毛鸭、红毛鸭、小鸭子(小鸭子还不会飞)

现在定义一个鸭子的父类:里面有都会叫的方法,有显示外观的方法(因为每只都不一样,就需要子类重写)

还会飞行 (这里使用策略模式)

public  abstract class duck {
    //鸭子都会叫:
    public void quack(){
        System.out.println("嘎嘎嘎");
    }
    //鸭子的外观,因为都不一样,所以由子类去实现
    public abstract void display();
	
	//以下使用策略模式:
    //在父类中持有该接口,并由该接口代替飞行行为(组合)
    private Flying flying;
    //提供set方法
    public void setFlying(Flying flying) {
        this.flying = flying;
    }
    public void fly(){
        flying.Fly();
    }
}

定义一个飞行接口:

/**
 * 策略接口:实现了鸭子的飞行行为
 */
public interface Flying {
    void Fly();
}

我们知道策略模式就是把需要用的算法封装起来,就在另一个内封装了会飞不会飞的两个方法:

会飞(继承至上面的飞行接口,重写飞行方法):

public class FlyWithWin implements Flying {
    @Override
    public void Fly() {
        System.out.println("我会飞");
    }
}

不会飞:

public class FlyNoWay implements Flying {
    @Override
    public void Fly() {
        System.out.println("我不会飞行");
    }
}

注意: 上面这两个方法我是把他们单独封装起来,当做算法族,然后程序需要使用里面某个算法的时候,程序不会受算法改变的影响,因为这里面的算法最终效果是一致的

红毛鸭类:

/**
 * 红色鸭子
 */
public class RedDuck extends duck{
    public RedDuck(){
        super();
        //给鸭子注入飞行的能力,这里就是通过算法族里面的会飞的算法
        super.setFlying(new FlyWithWin());
    }
    @Override
    public void display() {
        System.out.println("我是红色的鸭子");
    }
}

绿毛鸭:

/**
 *
 * 绿色鸭子
 */
public class GreenDuck extends duck{
    public GreenDuck(){
        super();
        //给鸭子注入飞行的能力,这里也是通过算法族里面的会飞的算法
        super.setFlying(new FlyWithWin());
    }
    @Override
    public void display() {
        System.out.println("我是绿色的鸭子");
    }
}

小鸭子类(不会飞):

/**
 * 小鸭子,还不会飞
 */
public class SamllDuck extends duck{
    public SamllDuck(){
        super();
        //小鸭子不会飞,所以使用了算法族里面不会飞的算法
        super.setFlying(new FlyNoWay());
    }

    @Override
    public void display() {
        System.out.println("我还是小鸭子");
    }
    //因为小鸭子和大鸭子的叫声不一样,所以重写叫声方法
    public void quack(){
        System.out.println("嘎~嘎~嘎");
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        System.out.println("***测试鸭子程序***");
        duck d = null;
		//这下面是轮流运行!!!!  
        d = new RedDuck();  //测试红色的鸭子
        d = new GreenDuck();  //测试绿色的鸭子
        d = new SamllDuck();  //测试小鸭子
        d.display();
        d.quack();
        d.fly();
        System.out.println("***测试完毕***");
    }
}

当使用红毛鸭为对象时:

***测试鸭子程序***
我是红色的鸭子
嘎嘎嘎
我会飞
***测试完毕***

当使用绿毛鸭为对象时:

***测试鸭子程序***
我是绿色的鸭子
嘎嘎嘎
我会飞
***测试完毕***

当使用小鸭子为对象时:

***测试鸭子程序***
我还是小鸭子
嘎~嘎~嘎
我不会飞行
***测试完毕***

5、策略模式的应用场景

1.一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中

2.一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句

3.系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时

4.系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构

5.多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注猪先飞的更多内容!     

原文出处:https://blog.csdn.net/m0_57310550/article/details/123537164

[!--infotagslink--]

相关文章

  • Java实现经典游戏复杂迷宫

    这篇文章主要介绍了如何利用java语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
  • java 运行报错has been compiled by a more recent version of the Java Runtime

    java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01
  • 在java中获取List集合中最大的日期时间操作

    这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
  • 教你怎么用Java获取国家法定节假日

    这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
  • Java如何发起http请求的实现(GET/POST)

    这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
  • 浅谈Java与C#的一些细微差别

    说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
  • javascript设计模式之解释器模式详解

    神马是“解释器模式”?先翻开《GOF》看看Definition:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。在开篇之前还是要科普几个概念: 抽象语法树: 解释器模式并未解释如...2014-06-07
  • Postgresql 如何选择正确的关闭模式

    这篇文章主要介绍了Postgresl 如何选择正确的关闭模式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-18
  • 解决Java处理HTTP请求超时的问题

    这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
  • 学习JavaScript设计模式之装饰者模式

    这篇文章主要为大家介绍了JavaScript设计模式中的装饰者模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下...2016-01-21
  • java 判断两个时间段是否重叠的案例

    这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
  • 超简洁java实现双色球若干注随机号码生成(实例代码)

    这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
  • Java生成随机姓名、性别和年龄的实现示例

    这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
  • java 画pdf用itext调整表格宽度、自定义各个列宽的方法

    这篇文章主要介绍了java 画pdf用itext调整表格宽度、自定义各个列宽的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-31
  • 如何开启mysql中的严格模式

    很多集成的PHP环境(PHPnow WAMP Appserv等)自带的MySQL貌似都没有开启MySQL的严格模式,何为MySQL的严格模式,简单来说就是MySQL自身对数据进行严格的校验(格式、长度、类型等),比如一个整型字段我们写入一个字符串类型的数...2013-10-04
  • java正则表达式判断前端参数修改表中另一个字段的值

    这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
  • Java使用ScriptEngine动态执行代码(附Java几种动态执行代码比较)

    这篇文章主要介绍了Java使用ScriptEngine动态执行代码,并且分享Java几种动态执行代码比较,需要的朋友可以参考下...2021-04-15
  • Java开发实现人机猜拳游戏

    这篇文章主要介绍了Java开发实现人机猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-03
  • Java List集合返回值去掉中括号('[ ]')的操作

    这篇文章主要介绍了Java List集合返回值去掉中括号('[ ]')的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-29
  • mybatis-plus实体类主键策略有3种(小结)

    这篇文章主要介绍了mybatis-plus实体类主键策略有3种(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-27