DetailReader_Functional_Way.java
package FunctionalProgramming; import java.util.Collection; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; /** * @author longxingjian <longxingjian@kuaishou.com> * Created on 2020-01-14 */ public class DetailReader_Functional_Way { private Function<Long, String> cacheKeyFormatter; private List<Long> ids; public DetailReader_Functional_Way(Function<Long, String> function, List<Long> ids) { this.cacheKeyFormatter = function; this.ids = ids; } public List<String> convert() { List<String> convertedCacheKeys = ids.stream().map(cacheKeyFormatter).collect(Collectors.toList()); return convertedCacheKeys; } }这个对象虽然也有一个convert方法,但是我们看到这个方法没有任何的转换逻辑,它的转换逻辑是通过调用cacheKeyFormatter来实现的,而cacheKeyFormatter正是与数据ids一起定义在开头的一个成员,他是一个Function对象,从泛型中可以看出这个函数式对象提供的函数功能是输入Long型输出String型。
里看看这个对象是怎么传入的:
CacheKeyTest.java
package FunctionalProgramming; import java.util.ArrayList; import java.util.List; import org.junit.Test; /** * @author longxingjian * Created on 2020-01-14 */ public class CacheKeyTest { @Test public void cacheKeyTest() { List<Long> ids = new ArrayList<>(); ids.add(1L); ids.add(2L); DetailReader_Functional_Way detailReader = new DetailReader_Functional_Way(CacheKeyProvider::getCacheKey, ids); List<String> convertedKeys = detailReader.convert(); for (String key : convertedKeys) { System.out.println(key); } } }注意看DetailReader_Functional_Way detailReader = new DetailReader_Functional_Way(CacheKeyProvider::getCacheKey, ids);
这里我们通过函数指针为Function对象传入了CacheKeyProvider 的成员函数getCacheKey。
来看看CacheKeyProvider对象是如何定义的:
CacheKeyProvider.java
package FunctionalProgramming; /** * @author longxingjian * Created on 2020-01-14 */ public class CacheKeyProvider { final static String CACHE_KEY = "Number_%S_CACHE_KEY"; public static String getCacheKey(Long id) { return String.format(CACHE_KEY, id); } }运行CacheKeyTest.java:
梳理上述过程,我们发现java函数式编程的结果是通过提供一种特殊的对象--只提供一种服务的对象来实现对函数式编程的模拟。这种方式虽然也是在对象层面的解耦,但也实实在在的将数据与操作分离开来。在上面的实现中,我们可以通过在CacheKeyTest.java传入不同的函数指针而使用不同的函数逻辑,而不需要去修改DetailReader_Functional_Way.java中的业务代码。在DetailReader_Functional_Way.java中,处理逻辑和被处理的数据是放在对等的位置的。