讀函數式程式設計思維筆記05_現實應用 讀函數式程式設計思維筆記05_現實應用 1.Java 8 1.1.除了增加函數式特性,還增加了一些配合使用的文法糖衣 1.2.函數式接口 1.2.1.SAM(Single Abstract Method,單抽象方法)接口 1.2.1.1.含有單一方法的接口是Java的一種習慣用法 1.2.1.2.Runnable和Callable接口都是有代表性的例子 1.2.2.對舊有SAM接口的增強,它允許我們用lambda塊取代傳統的匿名類來就地執行個體化一個接口 1.3.預設方法 1.3.1.一些在接口類型中聲明的,以default關鍵字标記的,非抽象、非靜态的public方法(且帶有方法體定義) 1.4.mixin 1.4.1.介于接口和父類之間的一種結構 1.4.2.和接口一樣都是類型,都可以執行instanceof檢查,也都遵循一樣的擴充規則 1.4.3.Ruby、Groovy等類似語言也允許通過mixin的形式,在既有的類層次上增補功能 1.5.Optional類型 1.5.1.min()等内建方法都不直接傳回結果值,而是傳回一個Optional結構 1.5.2.提供了ifPresent()方法,可以用在終結操作的位置上,設定在僅當存在有效結果時執行的一個代碼塊 1.6.stream 1.6.1.不存儲值,隻擔當從輸入源引出的管道角色,一直連接配接到終結操作上産生輸出 1.6.2.盡可能做到緩求值 1.6.3.可以沒有邊界(無限長) 1.6.3.1.用limit()、findFirst()等方法來取得其一部分子集 1.6.4.用過之後必須重新生成新的stream才能再次操作 1.6.4.1.消耗品 1.6.5.操作分類 1.6.5.1.中間操作 1.6.5.1.1.一律傳回新的stream,并且總是緩求值的 1.6.5.2.終結操作 1.6.5.2.1.周遊stream,産生結果值和副作用 2.函數式的基礎設施 2.1.架構 2.1.1.架構永遠是取舍的結果 2.1.2.從根本上貫徹“值不可變”的思路,最大化地發揮其優點 2.1.2.1.Java不允許字典型集合中的鍵在它被集合引用期間發生取值的變化,值不可變的對象完全符合這項要求 2.1.2.2.Groovy用文法糖衣掩蓋了實作值不可變性的繁瑣細節 2.1.2.2.1.添加@Immutable标注 2.1.3.測試是為了确認代碼中成功地制造了我們需要的變化 2.1.3.1.測試的真正目的是對可變事物的檢驗——可變的事物越多,就需要越多的測試來保證其正确性 2.1.3.2.可變的狀态越多,要求的測試也越多。 2.1.4.值不可變的對象天生就是線程安全的,完全不會發生同步方面的問題 2.1.4.1.具有原子性的失敗(failure atomicity):隻要對象構造完畢,就不會再發生由值可變性引發的失敗 2.1.5.實作一個值不可變的Java類 2.1.5.1.把所有的字段都标記為final 2.1.5.1.1.要麼在聲明時初始化,要麼在構造器中初始化 2.1.5.2.把類标記為final,防止被子類覆寫 2.1.5.3.不要提供無參數的構造器 2.1.5.3.1.一個值不可變的對象,它的一切狀态都必須通過構造器來設定 2.1.5.3.2.值不可變的類根本不應該出現無參數的構造器 2.1.5.3.2.1.必須提供無參數的構造器,考慮用一個私有的無參數構造器來滿足架構的要求 2.1.5.3.2.2.私有的構造器仍然可以通過反射來通路 2.1.5.4.提供至少一個構造器 2.1.5.5.除了構造器之外,不要提供任何制造變化的方法 2.1.5.5.1.标記了final的對象引用并不等于它所指向的一切都不可改變 2.1.5.5.2.需要預防性地複制所有通過getXXX方法傳回的對象引用 2.1.6.指令-查詢職責隔離架構 2.1.6.1.(Command-Query Responsibility Segregation,CQRS) 2.1.7.最終一緻性(eventual consistency) 2.1.7.1.不對模型的變更操作施加硬性的時間限制,而隻是保證,當更新發生後,模型最終會回複到一緻的狀态 2.1.7.2.事務要求系統滿足ACID(即原子性Atomic、一緻性Consistent、隔離性Isolated、持久性Durable的縮寫)性質,而最終一緻性要求滿足BASE(即基本可用Basically Available、軟狀态Soft state、最終一緻性Eventual consistency的縮寫)性質 2.1.7.3.讀取與變更分離之後,邏輯可得到簡化 2.1.7.3.1.承擔讀取職責的部分可以全面實作值不可變的性質 2.2.Web架構 2.2.1.整個Web看作是一系列從請求到響應的變換 2.2.1.1.Web領域與函數式程式設計簡直是天作之合 2.2.2.路由架構 2.2.3.以函數作為路由的目标 2.2.4.領域專用語言(DSL) 2.2.4.1.表達能力有限,專門針對一個狹窄問題域的計算機程式設計語言 2.2.4.2.内部DSL是在其宿主語言之上構造出來的新“語言”,且利用宿主語言的文法糖衣來形成自身的風格 2.2.4.2.1.Ruby on Rails Web架構 2.2.4.2.2.C#語言的LINQ擴充 2.2.5.與建構工具緊密內建 2.2.5.1.和指令行的建構工具緊密內建,用建構工具來執行從生成新項目骨架到運作測試的一切任務 2.3.資料庫 2.3.1.Datomic是一種值不可變的資料庫 2.3.1.1.存儲值而非資料,它的空間利用效率并不低 2.3.1.2.進入到庫裡的每一筆事實都會被打上時間戳 2.3.1.3.在資訊上增加了時間的概念,使得每一筆事實都總是維持在正确的上下文裡 2.3.1.4.永久地記錄所有的schema變更和資料變更 2.3.1.5.讀取和寫入分離 2.3.1.5.1.Datomic擁有一個CQRS系統的内在 2.3.1.6.事件驅動型架構中的值不可變性和時間戳 2.3.1.6.1.依靠一個事件流來反映應用程式的狀态變化,而一個捕獲所有資訊并加上時間戳記的資料庫,正好可以完美地扮演事件流的角色,資料庫本身的特性即可滿足回退和重放事件的需求