函數(shù)式設(shè)計(jì):原則、模式與實(shí)踐(英文版) [美]羅伯特·C.馬丁
定 價(jià):129 元
- 作者:[美]羅伯特·C.馬丁
- 出版時(shí)間:2024/10/1
- ISBN:9787111760627
- 出 版 社:機(jī)械工業(yè)出版社
- 中圖法分類:TP312.8JA
- 頁(yè)碼:
- 紙張:膠版紙
- 版次:
- 開(kāi)本:32開(kāi)
本書(shū)是一本向程序員介紹如何有效使用函數(shù)式編程語(yǔ)言的實(shí)用指南。它側(cè)重于現(xiàn)實(shí)世界中的應(yīng)用,避免深入探討Monads、Monoids、Functors和Categories等理論方面的內(nèi)容,因?yàn)檫@些內(nèi)容已經(jīng)集成到常用語(yǔ)言、庫(kù)和框架中。相反,本書(shū)強(qiáng)調(diào)如何以及為什么要在日常軟件開(kāi)發(fā)中使用函數(shù)式編程,書(shū)中比較了Java等面向?qū)ο笳Z(yǔ)言和Clojure等函數(shù)式語(yǔ)言的編碼結(jié)構(gòu)。之所以選擇這些語(yǔ)言,是因?yàn)樗鼈兪褂脧V泛(Java)且簡(jiǎn)單(Clojure)。 本書(shū)還重點(diǎn)描述了用函數(shù)式方法構(gòu)建系統(tǒng)的設(shè)計(jì)和架構(gòu)原則,書(shū)中使用了統(tǒng)一建模語(yǔ)言(Unified Modeling Language,UML)圖,并參考了軟件設(shè)計(jì)的SOLID原則、設(shè)計(jì)模式,以及整潔架構(gòu)的概念。
在本書(shū)中,著名軟件工程師Bob大叔解釋了為何使用函數(shù)式編程,以及如何做才能為客戶構(gòu)建更好的系統(tǒng)。Bob大叔將Java中傳統(tǒng)的面向?qū)ο蟮木幊探Y(jié)構(gòu)與函數(shù)式語(yǔ)言所支持的編程結(jié)構(gòu)進(jìn)行了對(duì)比,確定了每種結(jié)構(gòu)的作用,并展示了如何明智地在合理上下文中使用兩者來(lái)構(gòu)建更好的系統(tǒng)。作風(fēng)務(wù)實(shí)的Bob大叔能用最少的理論講清并解決“真刀真槍”的實(shí)戰(zhàn)問(wèn)題。通過(guò)易于理解的示例,開(kāi)發(fā)人員能發(fā)現(xiàn)易于學(xué)習(xí)且語(yǔ)義豐富的Clojure語(yǔ)言如何幫助他們提高代碼的整潔性、設(shè)計(jì)性、紀(jì)律性和成效性。Bob大叔還從函數(shù)式的視角研究了著名的SOLID原則和GOF設(shè)計(jì)模式,揭示了模式對(duì)于函數(shù)式程序員仍極具價(jià)值的原因,以及使用它們來(lái)實(shí)現(xiàn)卓越成效的方法。通過(guò)閱讀本書(shū),你將能夠:?理解函數(shù)式編程基礎(chǔ):不變性、持久性數(shù)據(jù)、遞歸、迭代、惰性和狀態(tài)性;?通過(guò)精心設(shè)計(jì)的案例研究對(duì)比函數(shù)式方法和面向?qū)ο蠓椒ǎ?探索數(shù)據(jù)流的函數(shù)式設(shè)計(jì)技術(shù);?使用經(jīng)典的SOLID原則編寫(xiě)更好的Clojure代碼;? 掌握實(shí)現(xiàn)函數(shù)式測(cè)試、GUI和并發(fā)性的實(shí)用方法;?在函數(shù)式編程中充分利用設(shè)計(jì)模式;?逐步構(gòu)建企業(yè)級(jí)Clojure應(yīng)用程序。
前 言
這是一本為每日編寫(xiě)代碼的程序員所寫(xiě)的書(shū),目的是幫助他們了解如何使用函數(shù)式編程語(yǔ)言來(lái)完成實(shí)際的任務(wù)。因此,我不會(huì)花太多時(shí)間去探討函數(shù)式編程的理論,如Monads、Monoids、Functors、Categories等。這并不是說(shuō)這些理論不正確、無(wú)價(jià)值或不相關(guān),而是因?yàn)樗鼈兺ǔ2粫?huì)出現(xiàn)在程序員的日常工作中。這些理論已經(jīng)與常見(jiàn)的語(yǔ)言、代碼庫(kù)和框架融為了一體。如果對(duì)函數(shù)式理論感興趣,推薦閱讀Mark Seemann的著作。
本書(shū)探討的是如何(以及為何要)在日常工作中使用函數(shù)式編程為真實(shí)的客戶構(gòu)建真實(shí)的系統(tǒng)。接下來(lái)我們將比較下面兩種常見(jiàn)的代碼結(jié)構(gòu)——面向?qū)ο笳Z(yǔ)言(如Java)和函數(shù)式語(yǔ)言(如Clojure)。
我之所以選擇這兩種語(yǔ)言,是因?yàn)镴ava使用得非常廣泛,Clojure則極容易學(xué)習(xí)。
函數(shù)式編程和過(guò)程式編程簡(jiǎn)史
1936年,艾倫·圖靈(Alan Turing)和阿隆佐·丘奇(Alonzo Church)這兩位數(shù)學(xué)家獨(dú)立解決了大衛(wèi)·希爾伯特(David Hilbert)所提出的著名難題之一:可判定性問(wèn)題。雖然由于前言的篇幅限制,我們無(wú)法詳細(xì)描述這個(gè)問(wèn)題,但只需知道這與尋找整數(shù)公式的通解有關(guān)即可。這與我們所討論的主題相關(guān),因?yàn)閿?shù)字計(jì)算機(jī)中的每個(gè)程序其實(shí)都是一個(gè)整數(shù)公式。
這兩位數(shù)學(xué)家獨(dú)立地證明了這樣的通解不存在。他們證明了存在這樣的整數(shù),它們永遠(yuǎn)不能由比該整數(shù)小的整數(shù)公式計(jì)算出來(lái)。另一種說(shuō)法是,存在計(jì)算機(jī)程序無(wú)法計(jì)算的數(shù)字。實(shí)際上,這就是艾倫·圖靈所使用的方法。在1936年所發(fā)表的著名論文中,圖靈發(fā)明了一種數(shù)字計(jì)算機(jī),并證明了即使給定無(wú)限的時(shí)間和空間,計(jì)算機(jī)也無(wú)法計(jì)算某些數(shù)字。
另外,丘奇通過(guò)他所發(fā)明的lambda演算(一種用于操作函數(shù)的數(shù)學(xué)形式化方法)得出了同樣的結(jié)論。通過(guò)對(duì)形式化方法邏輯的操作,他證明了存在無(wú)法解決的邏輯問(wèn)題。
圖靈的發(fā)明是所有現(xiàn)代數(shù)字計(jì)算機(jī)的前身。所有數(shù)字計(jì)算機(jī)實(shí)際上都是一臺(tái)(有限)圖靈機(jī)。所有在數(shù)字計(jì)算機(jī)上執(zhí)行的程序?qū)嶋H上都是一個(gè)圖靈機(jī)程序。
丘奇和圖靈后來(lái)合作證明了他們倆的方法是等價(jià)的。圖靈機(jī)中的每一個(gè)程序都可以用lambda演算來(lái)表示。反之亦然。
所有的函數(shù)式編程實(shí)際上都是lambda演算。
這兩種編程風(fēng)格在數(shù)學(xué)上是等價(jià)的。任何程序都可以使用過(guò)程式風(fēng)格(圖靈)或函數(shù)式風(fēng)格(丘奇)來(lái)編寫(xiě)。本書(shū)要探討的不是這種等價(jià)性,而是如何使用函數(shù)式方法影響程序的結(jié)構(gòu)和設(shè)計(jì)。我們將試圖確定函數(shù)式方法產(chǎn)生的結(jié)構(gòu)和設(shè)計(jì)是否優(yōu)于或劣于使用過(guò)程式方法所產(chǎn)生的結(jié)構(gòu)和設(shè)計(jì)。
關(guān)于Clojure
本書(shū)選擇Clojure是因?yàn)閷W(xué)習(xí)新語(yǔ)言比較難,如果同時(shí)學(xué)習(xí)新范式的話,更是難上加難。因此,為了簡(jiǎn)化學(xué)習(xí)任務(wù),我選擇了一門(mén)既足夠簡(jiǎn)單又能夠讓我們學(xué)習(xí)函數(shù)式編程和函數(shù)式設(shè)計(jì)的語(yǔ)言。
Clojure語(yǔ)義豐富且語(yǔ)法簡(jiǎn)單。語(yǔ)法簡(jiǎn)單意味著學(xué)習(xí)起來(lái)比較輕松。學(xué)習(xí)Clojure的難點(diǎn)都在語(yǔ)義方面。雖然代碼庫(kù)和習(xí)慣用法需要很大的努力去內(nèi)化,但學(xué)習(xí)語(yǔ)言本身幾乎不費(fèi)力氣。希望本書(shū)能提供一種學(xué)習(xí)和欣賞函數(shù)式編程的方法,其間不會(huì)讓大家因新語(yǔ)言的語(yǔ)法而分心。
話雖如此,但本書(shū)并不是Clojure教程。在前幾章中,我會(huì)解釋一些Clojure的基礎(chǔ)知識(shí)并使用一些解釋性的腳注。同時(shí),也期望親愛(ài)的讀者去做功課并查找相關(guān)資料。有幾個(gè)很好的網(wǎng)站可供查詢,我最喜歡的網(wǎng)站是https://clojure.org/api/cheatsheet。
本書(shū)會(huì)使用speclj測(cè)試框架。隨著內(nèi)容的展開(kāi),測(cè)試代碼會(huì)越來(lái)越多。它與其他受歡迎的測(cè)試框架非常相似,因此在閱讀過(guò)程中,熟悉它的各種功能并不難。
關(guān)于架構(gòu)和設(shè)計(jì)
本書(shū)的重點(diǎn)是描述用函數(shù)式方法構(gòu)建的系統(tǒng)的設(shè)計(jì)和架構(gòu)原則。為此,我將使用統(tǒng)一建模語(yǔ)言(Unified Modeling Language,UML)圖,并參考軟件設(shè)計(jì)的SOLID原則、設(shè)計(jì)模式,以及整潔架構(gòu)的概念。不用擔(dān)心,書(shū)中會(huì)解釋這些概念,并引用許多外部參考資料供你查閱。
關(guān)于面向?qū)ο?br />許多人都認(rèn)為,面向?qū)ο缶幊毯秃瘮?shù)式編程互不兼容。本書(shū)應(yīng)該能夠證明事實(shí)并非如此。本書(shū)中的程序、設(shè)計(jì)和架構(gòu)是函數(shù)式和面向?qū)ο蟾拍畹娜诤象w。根據(jù)經(jīng)驗(yàn),我堅(jiān)定地認(rèn)為,這兩種風(fēng)格是完全兼容的。好的程序員可以并且應(yīng)該將兩者兼收并蓄,相互為用。
關(guān)于“函數(shù)式”
本書(shū)會(huì)使用“函數(shù)式”這個(gè)術(shù)語(yǔ),并對(duì)其進(jìn)行定義和闡述。隨著內(nèi)容的展開(kāi),我也會(huì)對(duì)這個(gè)概念做一些修正。有些例子雖然是用函數(shù)式語(yǔ)言和函數(shù)式風(fēng)格編寫(xiě)的,但并不是純粹的函數(shù)式。在大多數(shù)情況下,我會(huì)為“函數(shù)式”這個(gè)詞加上引號(hào),并使用腳注指出所做的修正。
為何要做修正?因?yàn)楸緯?shū)強(qiáng)調(diào)的是實(shí)用,而非理論。從函數(shù)式風(fēng)格中獲得好處(而不是嚴(yán)格遵循理論)會(huì)更有趣。正如我們將在第1章中看到的,接受用戶提供的輸入?yún)?shù)的“函數(shù)”并不是純粹的函數(shù)式,但本書(shū)會(huì)在需要實(shí)用性的地方使用這樣的“函數(shù)”。
本書(shū)所有示例的源代碼都存放在一個(gè)GitHub倉(cāng)庫(kù)中,地址為https://github.com/unclebob/FunctionalDesign。
羅伯特·C. 馬。˙ob大叔)
世界著名編程大師,敏捷開(kāi)發(fā)和設(shè)計(jì)模式先驅(qū),從事軟件開(kāi)發(fā)相關(guān)工作超過(guò)50年。他是“SOLID五大原則”的奠基人、“敏捷宣言”聯(lián)合簽署人、“敏捷聯(lián)盟”首任主席、C++ Report雜志前主編。他發(fā)表了大量有影響力的文章,并經(jīng)常受邀在許多國(guó)際軟件大會(huì)上發(fā)表演講。他創(chuàng)立了Uncle Bob Consulting有限責(zé)任公司,并與兒子Micah Martin共同創(chuàng)立了Clean Coders有限責(zé)任公司。他還是Clean Code、Clean Architecture和The Clean Coder等多本暢銷書(shū)籍的作者。
目 錄
第一部分 函數(shù)式基礎(chǔ)
第1章 不變性3
什么是函數(shù)式編程4
賦值的問(wèn)題7
為什么叫它“函數(shù)式”10
沒(méi)有狀態(tài)改變嗎12
不變性概念15
第2章 持久性數(shù)據(jù)17
關(guān)于瞞天過(guò)海19
制作副本20
結(jié)構(gòu)共享23
第3章 遞歸和迭代27
迭代28
極簡(jiǎn)Clojure教程29
迭代概述32
TCO、Clojure和JVM32
遞歸32
第4章 惰性37
惰性累積40
為何需要惰性41
尾聲42
第5章 狀態(tài)性43
何時(shí)必須“可變”47
軟件事務(wù)內(nèi)存48
生活不易,軟件更難51
第二部分 比較性分析
第6章 質(zhì)因數(shù)練習(xí)55
Java版56
Clojure版60
總結(jié)63
第7章 保齡球練習(xí)65
Java版66
Clojure版71
總結(jié)75
第8章 八卦公交司機(jī)練習(xí)77
Java版78
公交司機(jī)文件84
行車線路文件85
公交車站文件85
八卦故事文件86
模擬過(guò)程文件87
Clojure版88
總結(jié)93
第9章 面向?qū)ο缶幊?5
函數(shù)式工資問(wèn)題解決方案98
命名空間與源文件107
總結(jié)108
第10章 類型109
第三部分 函數(shù)式設(shè)計(jì)
第11章 數(shù)據(jù)流117
第12章 SOLID125
單一職責(zé)原則126
開(kāi)閉原則131
函數(shù)133
帶虛表的對(duì)象134
多重方法135
獨(dú)立部署136
里氏替換原則138
ISA原則142
這不對(duì)145
代表原則146
接口隔離原則147
不需要就別依賴150
為什么151
總結(jié)151
依賴倒置原則152
回憶殺155
違背依賴倒置原則165
總結(jié)179
第四部分 函數(shù)式實(shí)用主義
第13章 測(cè)試183
REPL184
Mock184
基于性質(zhì)的測(cè)試186
診斷技術(shù)190
函數(shù)式197
第14章 GUI199
用Quil進(jìn)行海龜繪圖200
第15章 并發(fā)性215
總結(jié)225
第五部分 設(shè)計(jì)模式
第16章 設(shè)計(jì)模式回顧229
函數(shù)式編程中的模式233
抽象服務(wù)器模式233
適配器模式236
那真的是適配器對(duì)象嗎241
命令模式242
撤銷245
組合模式249
函數(shù)式254
裝飾器模式260
訪問(wèn)者模式264
To Close or to Clojure267
90°問(wèn)題270
抽象工廠模式274
90°問(wèn)題重現(xiàn)279
類型安全嗎281
總結(jié)281
補(bǔ)充:面向?qū)ο笫嵌舅巻?82
第六部分 案例研究
第17章 Wa-Tor小游戲287
如鯁在喉309
解決問(wèn)題312
讓魚(yú)瘋狂繁殖322
對(duì)于鯊魚(yú)324
總結(jié)335
后記337
索引341