用函数式写法精简 Java 代码的一个例子
在写代码的时候,经常遇到做一些判断,并在不同条件下执行不同操作。java中还会经常判断一个对象是否为null,并针对是和否两种情况分别进行处理。
一下用一个小例子说明,同一个逻辑,用函数式和非函数式写出来是什么样子。之后简要地探讨了二者的区别。这个例子是实际中遇到。我们有不同类别的文档索引在elasticsearch中,如果指定了具体的类别,则用该类别对应的indexer返回的查询语句。如果没有指定类别或者有多个类别,则默认在全部类别搜索。
类别和其对应的Indexer保存在indexerMap,categories是用户传进来的类别列表。
函数式的写法,有如下好处:
紧凑。整个执行流依次往下,如果执行途中有异常,则算子函数会自动处理。因此,写逻辑的时候,只需要关注happy path即可。即便执行过程中出现了异常,需要用一个替代方案挽救,也就只是多一个算子而已。
临时变量不见了。同样的逻辑,非函数写法需要定义各种临时变量来存储中间结果。多多的临时变量,不够优雅。
null不见了。任何没值的情况都可以看做是异常。将异常的处理隐匿于算子之后,让视野所见的代码干净整洁。
函数式和非函数式,是两种不同的思考方式,也是两种不同的语言(如英语和汉语之类)。同样的事务,二者都可以描述,但描述的优雅程度不同。熟悉函数式的思考方式之后,人的思维也会潜移默化地被塑造,思考问题也开始变得函数式起来。
算子(map、flatMap以及filter等)把一些常见的逻辑事先实现出来,等到写具体逻辑的时候,只需要简单的拼凑即可完成逻辑的编写了。
受函数式语言的启发,我实现了一个java版的函数式lib。其中Option对象有两个子类,Some和None,分别代表有值和无值。java自带的Optional也有类似功能,但当处理过程中有异常时,Optional并不记录这种异常。因此,我在自己的Option版本中,加入了异常信息,让None可以携带Exception从执行流的上游流到下游。其中,也对异步编程做了一点抽象,值得体验一下。
版权声明: 本文为 InfoQ 作者【Sean】的原创文章。
原文链接:【http://xie.infoq.cn/article/0c65411011808a8812df1757a】。文章转载请联系作者。
评论 (1 条评论)