2015-10-22 采用Java 8中Lambda表达式和默认方法的模板方法模式

原文链接 作者: Mohamed Sanaulla

  模板方法模式是“四人帮”(译者注:Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides)所著《Design Patterns book》一书中所描述的23种设计模式其中的一种,该模式旨在:

“Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. TemplateMethod lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure”。

  即模板方法定义一个算法的架构,并将某些步骤推迟到子类中实现。模板方法允许子类在不改变算法架构的情况下,重新定义算法中某些步骤。

  为了以更简单的术语描述模板方法,考虑这个场景:假设在一个工作流系统中,为了完成任务,有4个任务必须以给定的执行顺序执行。在这4个任务中,不同工作流系统的实现可以根据自身情况自定义任务的执行内容。

  模板方法可以应用在上述场景中:将工作流系统的4个核心任务封装到抽象类当中,如果任务可以被自定义,则将可自定义的任务推迟到子类中实现。

阅读全文

2015-10-21 Predicate和Consumer接口– Java 8中java.util.function包下的接口

原文链接 作者: Mohamed Sanaulla

  早先我写了一篇《函数式接口》,探讨了Java8中函数式接口的用法。如果你正在浏览Java8的API,我也提及了Predicate接口属于java.util.function包,在这篇文章中,我将展示如何应用Predicate接口和Consumer接口。

  一起看一下Predicate的官方文档::

Determines if the input object matches some criteria.

  即判断输入的对象是否符合某个条件。

阅读全文

2015-10-21 Function接口 – Java8中java.util.function包下的函数式接口

原文链接 作者: Mohamed Sanaulla

  早先我写了一篇《函数式接口》,探讨了Java8中函数式接口的用法。如果你正在浏览Java8的API,你会发现java.util.function中 Function, Supplier, Consumer, Predicate和其他函数式接口广泛用在支持lambda表达式的API中。这些接口有一个抽象方法,会被lambda表达式的定义所覆盖。在这篇文章中,我会简单描述Function接口,该接口目前已发布在java.util.function中。

  Function接口的主要方法:

R apply(T t) //将Function对象应用到输入的参数上,然后返回计算结果。

default <V> Function<T,V> //将两个Function整合,并返回一个能够执行两个Function对象功能的Function对象。

阅读全文

2015-10-20 Java中函数式编程的谓词函数(Predicates)第二部分

原文链接 作者: Cyrille Martraire

  在上一篇文章中我们介绍了谓词函数。通过一个简单的只带一个返回值是true或者false的函数的接口,把函数式编程语言的优势带入到了类似Java的面向对象编程语言中。这一小节,我们将会介绍一些高级特性,方便你高效利用谓词函数。

#测试

  在测试代码中使用谓词的优势尤为明显。当你需要测试一个混合了数据结构与某些条件逻辑的方法时,通过使用谓词,你可以先单独测试数据结构,再测试条件逻辑。

  第一步,先利用永真谓词或者永假谓词屏蔽用于判断的逻辑,将注意力集中在测试数据结构上:

 
// check with the always-true predicate

final Iterable<PurchaseOrder> all = orders.selectOrders(Predicates.<PurchaseOrder> alwaysTrue());

assertEquals(2, Iterables.size(all)); 

// check with the always-false predicat

eassertTrue(Iterables.isEmpty(orders.selectOrders(Predicates.<PurchaseOrder> alwaysFalse())));
    

  第二步,你可以分开测试每个谓词了:

 
final CustomerPredicate isForCustomer1 = new CustomerPredicate(CUSTOMER_1);

assertTrue(isForCustomer1.apply(ORDER_1)); // ORDER_1 is for CUSTOMER_1

assertFalse(isForCustomer1.apply(ORDER_2)); // ORDER_2 is for CUSTOMER_2
    

  例子简单,却见微知著。为了测试更加复杂的逻辑,你可能需要构建模拟谓词应对测试不够充分的情况。比如,一个第一次返回true,之后都返回false的谓词。通过严格分离关注点,谓词可以大大简化你的测试计划。

  如果你想测试驱动开发(TDD),谓词是一个不错的选择,如果你能通过测试的方式影响你的设计,之后你便会发现谓词很容易就融入到你的设计中。

阅读全文

2015-10-20 Java中函数式编程的谓词函数(Predicates)第一部分

原文链接 作者: Cyrille Martraire

  你一直在听说函数式编程将称霸整个编程届,而自己仍然沉浸在普通的Java里?请不要担心,因为你已经在日常Java代码中加入了函数式编程的特性。此外,函数式编程很有趣,能够帮你节省多行代码并且降低错误率。

#什么是谓词函数?

  许久之前,那时我还在用Java 1.4进行编码,当我第一次发现Apache Commons Collections,便爱上了谓词函数。Apache Commons Collections里的谓词函数仅仅只是一个只有一个方法的接口:

 
evaluate(Object object): boolean
    

  这就是谓词函数,输入一个对象,返回true或者false。最近诞生了类似Apache Commons Collections的持有Apache 2.0许可的Google Guava。在Google Guava中,定义了Predicate接口,该接口包含一个带有泛型参数的方法:

 
apply(T input): boolean
    

  如果想在程序中使用谓词函数,只需要利用自己的逻辑实现该接口即可。

阅读全文