Java函数式编程——通过行为参数化传递代码

createh52周前 (12-17)技术教程18

日新月异的需求

作为程序员,有一个很常见的问题是,同样的东西,用户的需求会经常改变

像我们之前找苹果的例子,需求经常变在动,如果都实现,那不得累死我们程序员?

如何应对多变的需求

  • 这里展示一个案例,并且逐步改善
  • 筛选绿苹果
  • 如果需求变成筛选红苹果,那我们需要拷贝这个方法,把Green换成Red。这样就违反了DRY
  • 我们可以把颜色作为参数
  • 仅仅改变颜色,把颜色传递进去,可以省去一个方法

此时又有新的需求:要区分重的苹果和轻的苹果:

行为参数化

  • 经过上面的案例,我们需要一种更好的方式来应对变化的需求。
  • 建模如下:你考虑的是苹果,需要根据Apple的某些属性,返回一个满足条件的boolean值。
  • 我们称之为谓词,定义接口如下

可以使用ApplePredicate的多个实现来执行不同的行为

这些实现,就是不同的筛选条件,算法就是 ApplePredicate。怎么去利用这种不同的实现呢?需要filterApples方法接受ApplePredicate对象,对Apple做条件测试。那么现在就来修改之前的代码:

现在你把filterApples方法迭代集合的逻辑与你要应用到集合中每个元素的行为(这里是一个谓词)区分开了。

  • 这样一来,任何需求的变更,只需要增加相应的实现类即可。filterApples方法的行为取决于你通过ApplePredicate对象传递的代码。但是会有一个问题:类膨胀
  • 代码传递/行为
  • 在上述的实现中,我们发现,对于整个测试,唯一重要的就是test方法的实现,这个方法决定了需要怎么样进行过滤。
  • 所以在传递行为的时候,我们可以直接使用匿名内部类来传递,如下
  • 对于多个无用的代码,把匿名内部类更改为Lambda表达式就行

    • 新需求,对苹果进行遍历,然后对其进行格式化输出
    • 这个需求需要定义一个新的方法,prettyPrintApple,整体的执行框架如下
    • ???就是我们要填充的部分:输入一个Apple,然后输出一个String,来定义一个接口 FormatApple


    prettyPrintApple 就可以实现了,如下

    • 这样就可以表示多种行为了
    • 到这里,我们可以将类、匿名类、Lambda进行行为参数化,替代了之前的案例中的值参数化。
    • 现在我们发现上述的ApplePredicate只能处理Apple,且filterApples也只能处理Apple,所以我们将这部分使用泛型进行抽象化,如下
    • 其他的行为参数化案例
    • 对集合进行排序,根据苹果颜色排序或者根据大小排序
    • 在Java 8中,List自带了一个sort方法(也可选择Collections.sort)排序
    • sort的行为可以用java.util.Comparator对象来参数化,它的接口如下

    你可以随时创建Comparator的实现,用sort方法表现出不同的行为。比如,你可以使用匿名类,按照重量升序对库存排序

    Lambda表达式

    小结

    • 行为参数化,就是一个方法接受多个不同的行为作为参数,并在内部使用它们,完成不同行为的能力。
    • 行为参数化可让代码更好地适应不断变化的要求,减轻未来的工作量。
    • 传递代码,就是将新行为作为参数传递给方法。但在Java 8之前这实现起来很啰嗦,在Java 8之前可以用匿名类来减少。
    • Java API包含很多可以用不同行为进行参数化的方法,包括排序、线程和GUI处理。

    相关文章

    Java启动参数设置 java启动参数设置java.exe名字

    set JAVA_OPTS=-Xms4g -Xmx4g -Xmn3g -XX:SurvivorRatio=6 -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=2...

    腾讯大佬详细讲解Java 启动exe程序,传递参数和获取参数

    这篇文章主要介绍了java 启动exe程序,传递参数和获取参数操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧1、java中启动exe程序 ,并添加传参String[] cmd =...

    Java程序的入口参数——main方法详解

    //Java程序的入口参数——main方法public static void main(String[] args){......}public修饰符:Java类调用由JVM调用,为了让JVM可以自...

    WebService的发布与调用 webservices调用

    WebService 简介首先先说一下,什么是webService,webService也是一种CS结构的WEB服务,C呢就是Client(客户端),S呢就是Server(服务端),webServic...

    java面试题|JVM调优常用JVM参数代码实例简介

    JVM(Java Virtual Machine)启动参数用于配置Java应用程序的运行时环境,包括内存管理、垃圾回收(GC)算法、性能调优和日志记录等。# JVM启动参数,不换行格式 # 设置堆内...

    基于容器的Java内存参数解析 java内置容器

    在基于物理的服务器(此处主要与容器平台进行区分,故此描述)上运行Java应用程序时,我们通常会使用Java虚拟机参数"-Xms、-Xmx"来指定Java堆内存的初始值和最大值。如果要将...