內容介紹
本書是第一本領域專用語言(DSL)的實戰類圖書,它面向真正的實踐者,是一本讓奮戰在開發第一線的實幹家備感實用的專著!《領域專用語言實戰》基於一系列JVM語言(Java、Ruby、Groovy、Scala和Clojure),分析了它們在實現DSL中的優劣勢,同時也給出了豐富的示例。如果你是一位架構師,希望設計出極具表現力的API,讓它既能滿足領域用戶的需要,又能達到高效開發的要求;如果你是一位有技術背景的特定領域用戶,期待著改善與開發團隊的溝通效果;如果你是一名程式設計師,正為如何與領域用戶對接業務規則而苦惱……那么,請看這本書。
本書分三部分,以金融中介系統為例全面細緻介紹從頭設計、實現與使用領域專用語言的方方面面。它不僅講解了DSL的實現手法,而且從最基本的技術入手,逐漸深入到高級技術,如元編程、解析器組合子,以及ANTLR、Xtext等開發框架。看完這本書,你將全面、深入地理解領域專用語言的定位、規範、術語,同時還可以把它作為具體開發工作的指導,學以致用,提高工作效率和質量。
作者介紹
作者簡介:Debasish Ghosh
Anshinsoft公司(http://www.anshinsoft.com)首席技術布道師,開發者推薦部落格“Ruminations of a Programmer”的作者,ACM協會高級會員。他擁有跨國IT企業20餘年工作經驗,擅長為各種客戶(無論是中小型公司還是財富500強企業)交付企業級解決方案,對自己將軟體設計和編程最佳實踐制度化而引以為傲,熱愛Java、Ruby、Scala、OO及函式式編程,關注DSL和NoSQL資料庫。電子郵件:[email protected]。Twitter賬號:@debasishg。
譯者簡介:
郭曉剛
大學肄業,有過兩次創業和創業失敗的經驗,從嵌入式硬體到企業軟體開發皆無所成。作為愛好的翻譯反倒堅持不輟,積攢了五六本獨譯、合譯的作品。長期在InfoQ中文站從事編輯工作,順帶磨練了技術觸覺和翻譯、寫作的技藝。現在家照顧本書拖稿期間出生的兒子。
作品目錄
第一部分 領域專用語言入門第1章 初識DSL2
1.1 問題域與解答域2
1.1.1 問題域3
1.1.2 解答域3
1.2 領域建模:確立共通的語彙4
1.3 初窺DSL6
1.3.1 何為DSL7
1.3.2 流行的幾種DSL8
1.3.3 DSL 的結構10
1.4 DSL 的執行模型11
1.5 DSL 的分類13
1.5.1 內部DSL13
1.5.2 外部DSL14
1.5.3 非文本DSL15
1.6 何時需要DSL15
1.6.1 優點16
1.6.2 缺點16
1.7 DSL 與抽象設計17
1.8 小結18
1.9 參考文獻18
第2章 現實中的DSL19
2.1 打造首個Java DSL20
2.1.1 確立共通語彙21
2.1.2 用Java 完成的首個實現21
2.2 創造更友好的DSL24
2.2.1 用XML 實現領域的外部化25
2.2.2 Groovy:更具表現力的實現語言25
2.2.3 執行Groovy DSL27
2.3 DSL 實現模式28
2.3.1 內部DSL 模式:共性與差異性29
2.3.2 外部DSL 模式:共性與差異性35
2.4 選擇DSL 的實現方式39
2.5 小結41
2.6 參考文獻42
第3章 DSL 驅動的應用程式開發43
3.1 探索DSL 集成44
3.2 內部DSL 的集成模式47
3.2.1 通過Java 6 的腳本引擎進行集成48
3.2.2 通過DSL 包裝器集成52
3.2.3 語言特有的集成功能59
3.2.4 基於Spring 的集成61
3.3 外部DSL 集成模式62
3.4 處理錯誤和異常64
3.4.1 給異常命名64
3.4.2 處理輸入錯誤65
3.4.3 處理異常的業務狀態66
3.5 管理性能表現67
3.6 小結68
3.7 參考文獻68
第二部分 實現DSL
第4章 內部DSL 實現模式70
4.1 充實DSL“工具箱”71
4.2 內嵌式DSL:元編程模式72
4.2.1 隱式上下文和靈巧API73
4.2.2 利用動態裝飾器的反射式元編程78
4.2.3 利用buider 的反射式元編程83
4.2.4 經驗總結:元編程模式85
4.3 內嵌式DSL:類型化抽象模式86
4.3.1 運用高階函式使抽象泛化86
4.3.2 運用顯式類型約束建模領域邏輯93
4.3.3 經驗總結:類型思維95
4.4 生成式DSL:通過模板進行運行時代碼生成96
4.4.1 生成式DSL 的工作原理97
4.4.2 利用Ruby 元編程實現簡潔的DSL 設計97
4.5 生成式DSL:通過宏進行編譯時代碼生成100
4.5.1 開展Clojure 元編程100
4.5.2 實現領域模型102
4.5.3 Clojure 宏之美103
4.6 小結104
4.7 參考文獻105
第5章 Ruby、Groovy、Clojure 語言中的內部DSL 設計106
5.1 動態類型成就簡潔的DSL107
5.1.1 易讀107
5.1.2 鴨子類型108
5.1.3 元編程——又碰面了110
5.1.4 為何選擇Ruby、Groovy、Clojure111
5.2 Ruby 語言實現的交易處理DSL112
5.2.1 從API 開始113
5.2.2 來點猴子補丁115
5.2.3 設立DSL 解釋器116
5.2.4 以裝飾器的形式添加領域規則119
5.3 指令處理DSL:精益求精的Groovy實現123
5.3.1 指令處理DSL 的現狀123
5.3.2 控制元編程的作用域124
5.3.3 收尾工作127
5.4 思路迥異的Clojure 實現128
5.4.1 建立領域對象129
5.4.2 通過裝飾器充實領域對象130
5.4.3 通過REPL 進行的DSL 會話134
5.5 告誡135
5.5.1 遵從最低複雜度原則135
5.5.2 追求適度的表現力135
5.5.3 堅持優秀抽象設計的各項原則136
5.5.4 避免語言間的摩擦136
5.6 小結137
5.7 參考文獻138
第6章 Scala 語言中的內部DSL設計139
6.1 為何選擇Scala140
6.2 邁向Scala DSL 的第一步141
6.2.1 通過Scala DSL 測試Java對象142
6.2.2 用Scala DSL 作為對Java 對象的包裝142
6.2.3 將非關鍵功能建模為ScalaDSL142
6.3 正式啟程142
6.3.1 語法層面的表現力143
6.3.2 建立領域抽象144
6.4 製作一種創建交易的DSL147
6.4.1 實現細節148
6.4.2 DSL 實現模式的變化152
6.5 用DSL 建模業務規則153
6.5.1 模式匹配如同可擴展的Visitor模式153
6.5.2 充實領域模型155
6.5.3 用DSL 表達稅費計算的業務規則157
6.6 把組件裝配起來160
6.6.1 用trait 和類型組合出更多的抽象160
6.6.2 使領域組件具體化161
6.7 組合多種DSL162
6.7.1 擴展關係的組合方式163
6.7.2 層級關係的組合方式167
6.8 DSL 中的Monad 化結構171
6.9 小結175
6.10 參考文獻176
第7章 外部DSL 的實現載體178
7.1 解剖外部DSL179
7.1.1 最簡單的實現形式179
7.1.2 對領域模型進行抽象179
7.2 語法分析器在外部DSL 設計中的作用182
7.2.1 語法分析器、語法分析器生成器183
7.2.2 語法制導翻譯184
7.3 語法分析器的分類190
7.3.1 簡單的自頂向下語法分析器191
7.3.2 高級的自頂向下語法分析器192
7.3.3 自底向上語法分析器193
7.4 工具支持下的DSL 開發——Xtext194
7.4.1 文法規則和大綱視圖195
7.4.2 文法的元模型197
7.4.3 為語義模型生成代碼198
7.5 小結201
7.6 參考文獻202
第8章 用Scala 語法分析器組合子設計外部DSL203
8.1 分析器組合子204
8.1.1 什麼是分析器組合子205
8.1.2 按照分析器組合子的方式設計DSL206
8.2 Scala 的分析器組合子庫207
8.2.1 分析器組合子庫中的基本抽象208
8.2.2 把分析器連線起來的組合子209
8.2.3 用Monad 組合DSL 分析器213
8.2.4 左遞歸DSL 語法的packrat分析214
8.3 用分析器組合子設計DSL 的步驟217
8.3.1 第一步:執行文法218
8.3.2 第二步:建立DSL 的語義模型219
8.3.3 第三步:設計Order 抽象220
8.3.4 第四步:通過函式施用組合子生成AST221
8.4 一個需要packrat 分析器的DSL實例223
8.4.1 待解決的領域問題223
8.4.2 定義文法225
8.4.3 設計語義模型227
8.4.4 通過分析器的組合來擴展DSL語義229
8.5 小結231
8.6 參考文獻231
第三部分 DSL開發的未來趨勢
第9章 展望DSL 設計的未來.234
9.1 語言層面對DSL 設計的支持越來越充分235
9.1.1 對表現力的不懈追求235
9.1.2 元編程的能力越來越強237
9.1.3 S 表達式取代XML 充當載體237
9.1.4 分析器組合子越來越流行238
9.2 DSL 工作檯238
9.2.1 DSL 工作檯的原理239
9.2.2 使用DSL 工作檯的好處240
9.3 其他方面的工具支持241
9.4 DSL 的成長和演化242
9.4.1 DSL 的版本化242
9.4.2 DSL 平穩演化的最佳實踐242
9.5 小結244
9.6 參考文獻244
附錄A 抽象在領域建模中的角色246
A.1 設計得當的抽象應具備的特質246
A.1.1 極簡247
A.1.2 精煉247
A.1.3 擴展性和組合性247
A.2 極簡,只公開對外承諾的247
A.2.1 用泛化來保留演化餘地248
A.2.2 用子類型化防止實現的泄露248
A.2.3 正確實施實現繼承249
A.3 精煉,只保留自身需要的250
A.3.1 什麼是非本質的250
A.3.2 非本質複雜性250
A.3.3 撇除雜質251
A.3.4 用DI 隱藏實現細節252
A.4 擴展性提供成長的空間253
A.4.1 什麼是擴展性253
A.4.2 mixin:滿足擴展性的一種設計模式254
A.4.3 用mixin 擴展Map255
A.4.4 函式式的擴展性256
A.4.5 擴展性也可以臨時抱佛腳256
A.5 組合性,源自純粹257
A.5.1 用設計模式滿足組合性257
A.5.2 回歸語言259
A.5.3 副作用和組合性260
A.5.4 組合性與並發262
A.6 參考文獻262
附錄B 元編程與DSL 設計263
B.1 DSL 中的元編程263
B.1.1 DSL 實現中的運行時元編程264
B.1.2 DSL 實現中的編譯時元編程265
B.2 作為DSL 載體的Lisp268
B.2.1 Lisp 的特殊之處268
B.2.2 代碼等同於數據269
B.2.3 數據等同於代碼269
B.2.4 簡單到只分析列表結構的語法分析器270
B.3 參考文獻271
附錄C Ruby 語言的DSL 相關特性272
C.1 Ruby 語言的DSL 相關特性272
C.2 參考文獻275
附錄D Scala 語言的DSL 相關特性276
D.1 Scala 語言的DSL 相關特性276
D.2 參考文獻279
附錄E Groovy 語言的DSL 相關特性280
E.1 Groovy 語言的DSL 相關特性280
E.2 參考文獻282
附錄F Clojure 語言的DSL 相關特性283
F.1 Clojure 語言的DSL 相關特性283
F.2 參考文獻285
附錄G 多語言開發286
G.1 對IDE 的特性要求287
G.2 搭建Java 和Groovy 的混合開發環境287
G.3 搭建Java 和Scala 的混合開發環境 288
G.4 常見的多語言開發IDE288
索引290