函数式设计:原则、模式与实践(英文版) [美]罗伯特·C.马丁
定 价:129 元
- 作者:[美]罗伯特·C.马丁
- 出版时间:2024/10/1
- ISBN:9787111760627
- 出 版 社:机械工业出版社
- 中图法分类:TP312.8JA
- 页码:
- 纸张:胶版纸
- 版次:
- 开本:32开
本书是一本向程序员介绍如何有效使用函数式编程语言的实用指南。它侧重于现实世界中的应用,避免深入探讨Monads、Monoids、Functors和Categories等理论方面的内容,因为这些内容已经集成到常用语言、库和框架中。相反,本书强调如何以及为什么要在日常软件开发中使用函数式编程,书中比较了Java等面向对象语言和Clojure等函数式语言的编码结构。之所以选择这些语言,是因为它们使用广泛(Java)且简单(Clojure)。 本书还重点描述了用函数式方法构建系统的设计和架构原则,书中使用了统一建模语言(Unified Modeling Language,UML)图,并参考了软件设计的SOLID原则、设计模式,以及整洁架构的概念。
在本书中,著名软件工程师Bob大叔解释了为何使用函数式编程,以及如何做才能为客户构建更好的系统。Bob大叔将Java中传统的面向对象的编程结构与函数式语言所支持的编程结构进行了对比,确定了每种结构的作用,并展示了如何明智地在合理上下文中使用两者来构建更好的系统。作风务实的Bob大叔能用最少的理论讲清并解决“真刀真枪”的实战问题。通过易于理解的示例,开发人员能发现易于学习且语义丰富的Clojure语言如何帮助他们提高代码的整洁性、设计性、纪律性和成效性。Bob大叔还从函数式的视角研究了著名的SOLID原则和GOF设计模式,揭示了模式对于函数式程序员仍极具价值的原因,以及使用它们来实现卓越成效的方法。通过阅读本书,你将能够:?理解函数式编程基础:不变性、持久性数据、递归、迭代、惰性和状态性;?通过精心设计的案例研究对比函数式方法和面向对象方法;?探索数据流的函数式设计技术;?使用经典的SOLID原则编写更好的Clojure代码;? 掌握实现函数式测试、GUI和并发性的实用方法;?在函数式编程中充分利用设计模式;?逐步构建企业级Clojure应用程序。
前 言
这是一本为每日编写代码的程序员所写的书,目的是帮助他们了解如何使用函数式编程语言来完成实际的任务。因此,我不会花太多时间去探讨函数式编程的理论,如Monads、Monoids、Functors、Categories等。这并不是说这些理论不正确、无价值或不相关,而是因为它们通常不会出现在程序员的日常工作中。这些理论已经与常见的语言、代码库和框架融为了一体。如果对函数式理论感兴趣,推荐阅读Mark Seemann的著作。
本书探讨的是如何(以及为何要)在日常工作中使用函数式编程为真实的客户构建真实的系统。接下来我们将比较下面两种常见的代码结构——面向对象语言(如Java)和函数式语言(如Clojure)。
我之所以选择这两种语言,是因为Java使用得非常广泛,Clojure则极容易学习。
函数式编程和过程式编程简史
1936年,艾伦·图灵(Alan Turing)和阿隆佐·丘奇(Alonzo Church)这两位数学家独立解决了大卫·希尔伯特(David Hilbert)所提出的著名难题之一:可判定性问题。虽然由于前言的篇幅限制,我们无法详细描述这个问题,但只需知道这与寻找整数公式的通解有关即可。这与我们所讨论的主题相关,因为数字计算机中的每个程序其实都是一个整数公式。
这两位数学家独立地证明了这样的通解不存在。他们证明了存在这样的整数,它们永远不能由比该整数小的整数公式计算出来。另一种说法是,存在计算机程序无法计算的数字。实际上,这就是艾伦·图灵所使用的方法。在1936年所发表的著名论文中,图灵发明了一种数字计算机,并证明了即使给定无限的时间和空间,计算机也无法计算某些数字。
另外,丘奇通过他所发明的lambda演算(一种用于操作函数的数学形式化方法)得出了同样的结论。通过对形式化方法逻辑的操作,他证明了存在无法解决的逻辑问题。
图灵的发明是所有现代数字计算机的前身。所有数字计算机实际上都是一台(有限)图灵机。所有在数字计算机上执行的程序实际上都是一个图灵机程序。
丘奇和图灵后来合作证明了他们俩的方法是等价的。图灵机中的每一个程序都可以用lambda演算来表示。反之亦然。
所有的函数式编程实际上都是lambda演算。
这两种编程风格在数学上是等价的。任何程序都可以使用过程式风格(图灵)或函数式风格(丘奇)来编写。本书要探讨的不是这种等价性,而是如何使用函数式方法影响程序的结构和设计。我们将试图确定函数式方法产生的结构和设计是否优于或劣于使用过程式方法所产生的结构和设计。
关于Clojure
本书选择Clojure是因为学习新语言比较难,如果同时学习新范式的话,更是难上加难。因此,为了简化学习任务,我选择了一门既足够简单又能够让我们学习函数式编程和函数式设计的语言。
Clojure语义丰富且语法简单。语法简单意味着学习起来比较轻松。学习Clojure的难点都在语义方面。虽然代码库和习惯用法需要很大的努力去内化,但学习语言本身几乎不费力气。希望本书能提供一种学习和欣赏函数式编程的方法,其间不会让大家因新语言的语法而分心。
话虽如此,但本书并不是Clojure教程。在前几章中,我会解释一些Clojure的基础知识并使用一些解释性的脚注。同时,也期望亲爱的读者去做功课并查找相关资料。有几个很好的网站可供查询,我最喜欢的网站是https://clojure.org/api/cheatsheet。
本书会使用speclj测试框架。随着内容的展开,测试代码会越来越多。它与其他受欢迎的测试框架非常相似,因此在阅读过程中,熟悉它的各种功能并不难。
关于架构和设计
本书的重点是描述用函数式方法构建的系统的设计和架构原则。为此,我将使用统一建模语言(Unified Modeling Language,UML)图,并参考软件设计的SOLID原则、设计模式,以及整洁架构的概念。不用担心,书中会解释这些概念,并引用许多外部参考资料供你查阅。
关于面向对象
许多人都认为,面向对象编程和函数式编程互不兼容。本书应该能够证明事实并非如此。本书中的程序、设计和架构是函数式和面向对象概念的融合体。根据经验,我坚定地认为,这两种风格是完全兼容的。好的程序员可以并且应该将两者兼收并蓄,相互为用。
关于“函数式”
本书会使用“函数式”这个术语,并对其进行定义和阐述。随着内容的展开,我也会对这个概念做一些修正。有些例子虽然是用函数式语言和函数式风格编写的,但并不是纯粹的函数式。在大多数情况下,我会为“函数式”这个词加上引号,并使用脚注指出所做的修正。
为何要做修正?因为本书强调的是实用,而非理论。从函数式风格中获得好处(而不是严格遵循理论)会更有趣。正如我们将在第1章中看到的,接受用户提供的输入参数的“函数”并不是纯粹的函数式,但本书会在需要实用性的地方使用这样的“函数”。
本书所有示例的源代码都存放在一个GitHub仓库中,地址为https://github.com/unclebob/FunctionalDesign。
罗伯特·C. 马丁(Bob大叔)
世界著名编程大师,敏捷开发和设计模式先驱,从事软件开发相关工作超过50年。他是“SOLID五大原则”的奠基人、“敏捷宣言”联合签署人、“敏捷联盟”首任主席、C++ Report杂志前主编。他发表了大量有影响力的文章,并经常受邀在许多国际软件大会上发表演讲。他创立了Uncle Bob Consulting有限责任公司,并与儿子Micah Martin共同创立了Clean Coders有限责任公司。他还是Clean Code、Clean Architecture和The Clean Coder等多本畅销书籍的作者。
目 录
第一部分 函数式基础
第1章 不变性3
什么是函数式编程4
赋值的问题7
为什么叫它“函数式”10
没有状态改变吗12
不变性概念15
第2章 持久性数据17
关于瞒天过海19
制作副本20
结构共享23
第3章 递归和迭代27
迭代28
极简Clojure教程29
迭代概述32
TCO、Clojure和JVM32
递归32
第4章 惰性37
惰性累积40
为何需要惰性41
尾声42
第5章 状态性43
何时必须“可变”47
软件事务内存48
生活不易,软件更难51
第二部分 比较性分析
第6章 质因数练习55
Java版56
Clojure版60
总结63
第7章 保龄球练习65
Java版66
Clojure版71
总结75
第8章 八卦公交司机练习77
Java版78
公交司机文件84
行车线路文件85
公交车站文件85
八卦故事文件86
模拟过程文件87
Clojure版88
总结93
第9章 面向对象编程95
函数式工资问题解决方案98
命名空间与源文件107
总结108
第10章 类型109
第三部分 函数式设计
第11章 数据流117
第12章 SOLID125
单一职责原则126
开闭原则131
函数133
带虚表的对象134
多重方法135
独立部署136
里氏替换原则138
ISA原则142
这不对145
代表原则146
接口隔离原则147
不需要就别依赖150
为什么151
总结151
依赖倒置原则152
回忆杀155
违背依赖倒置原则165
总结179
第四部分 函数式实用主义
第13章 测试183
REPL184
Mock184
基于性质的测试186
诊断技术190
函数式197
第14章 GUI199
用Quil进行海龟绘图200
第15章 并发性215
总结225
第五部分 设计模式
第16章 设计模式回顾229
函数式编程中的模式233
抽象服务器模式233
适配器模式236
那真的是适配器对象吗241
命令模式242
撤销245
组合模式249
函数式254
装饰器模式260
访问者模式264
To Close or to Clojure267
90°问题270
抽象工厂模式274
90°问题重现279
类型安全吗281
总结281
补充:面向对象是毒药吗282
第六部分 案例研究
第17章 Wa-Tor小游戏287
如鲠在喉309
解决问题312
让鱼疯狂繁殖322
对于鲨鱼324
总结335
后记337
索引341