这是一本有关模式和函数式编程的书,其中的函数式编程采用了Scala和Clojure两种语言进行描述。在本书中,我们向读者展示了如何采用函数式方案来替代或最大程度地简化在面向对象编程中所使用的诸多通用模式,同时还介绍了一些在函数式世界中广泛使用的模式。
相比原来单一地采用面向对象编程,如果能结合使用这些函数式模式,那么程序员将变得更有效率,同时也能以一种更简洁且更具声明性风格的方式来解决问题。如果你是一名Java程序员,希望了解函数式编程能为你的工作效率带来多大的提升,或者你是一名刚刚开始使用Scala和Clojure的新手,尚不能玩转这些函数式的问题解决方案,那么本书就是为你而准备的。
在开始深入探讨这些内容之前,我想先来讲一个故事。尽管出于保护隐私的目的修改了一些名字,但这确实是一个真实的故事。
函数式编程故事一则
作者:Michael Bevilacqua-Linn,软件消防员
网站的服务器并没有宕机,但是大量的警报却接踵而来。我们对这个问题进行跟踪并定位到了对我们使用过的第三方API的一组变更。而正是这一组变更导致了我们这一端主要的数据问题。换句话说,我们并不知道这组变更具体改变了什么,也无法找到任何能说明这些变更的人。现在的情况就是,事实表明与该API交互的系统也使用了这些遗留代码,而唯一知道这些代码的运作方式的家伙却正在度假。这是一个大型系统:有足足50万行的Java和OSGi代码量。
大量寻求支持的电话如潮水般蜂拥而至,失望的客户不顾昂贵的花费,打来支持电话以寻求我们的帮助。必须快速修复这个问题。我启动了一个Clojure REPL,开始毫无头绪地用它来对问题API进行诊断。
我的老板把头探进了我的办公室。“进展如何?”他问道。“哦,正在处理。”我回应。十分钟之后,老板的老板来了。“怎么样了?”他问道。“在处理。”我回应道。又是十分钟过去了,大老板(老板的老板的老板)来了。“情况如何?”他问道。“还在搞呢。”我回应道。接下来我清净了半小时,直到CTO出现。“还在搞呢。”在他开口之前我就先开了腔。
一个小时后,我找出了变更的问题所在。我立马提出了一个方案,该方案可以在遗留代码的开发者回来彻底修复该问题前保持数据不被污染。我将编写的用于解决该问题的小程序转交给了运维团队,他们将该程序运行在了一个JVM的安全区域。至此,潮水般的支持电话戛然而止,每个人都松了一口气。
在大约一周之后的全体会议上,大老板对我上次编写的用于处理故障的Java程序表示了感谢。而我则微笑着告诉他:“那并不是Java。”
REPL是Clojure的交互式编程环境,它在这个故事里帮了很大的忙。然而,大多数的语言(尤其是非函数式的语言)都拥有相似的交互式编程环境,所以这并不是这个故事的全部。
本书将要介绍两种模式:模式21“领域特定语言”和模式15“操作链模式”。在圆满处理这场故障中,它们起到了关键作用。
在早些时候,我就编写了一个领域特定语言的小型实例来配合这些特别的API,即使这些API很庞大,很难从中识别出问题所在,这一方式也能帮助我快速地对这些API进行探查。除此之外,函数式编程所依赖的强大的数据转换工具,例如我们将在模式15中看到的例子,可以帮助我快速地编写代码来收拾故障引起的烂摊子。
……
——Colin Yates,QFI咨询公司技术小组负责人
“那些经验丰富的面向对象程序员,若想要尝试函数式风格,便是本书的理想读者,本书将会指引他们从熟悉的面向对象模式过渡到函数式模式。”
——Rod Hilton,时代华纳有线公司高级工程师
“本书为函数式模式与面向对象模式的函数式替代方案,分别设置了独立的章节,作者将函数式模式安排在书中偏后的部分,十分方便读者查阅。作为一名Scala程序员,我也能在书中学到一些新的技巧。”
——Justin James,康卡斯特软件工程师