The limits of language are the limits of one’s world.
— Ludwig Wittgenstein
核心概念#
電腦語言影響你如何思考問題,以及你如何思考溝通。每種語言都帶有一系列特性的流行詞:靜態 vs 動態型別、早期 vs 晚期綁定、函數式 vs OO、繼承模型、mixin、巨集——所有這些都可能暗示或模糊某些解決方案。
更重要的是,問題領域的語言也可能暗示一種程式設計解決方案。我們總是嘗試用應用程式領域的詞彙來寫程式碼。在某些情況下,務實的程式設計師可以更進一步——實際上用領域的詞彙、語法和語義來程式設計。
Tip 22 - Program Close to the Problem Domain(用接近問題領域的方式編程)
真實世界的領域語言範例#
| 工具 | 類型 | 說明 |
|---|---|---|
| RSpec | 內部 DSL | Ruby 的測試庫,測試用來反映你期望程式碼的行為 |
| Cucumber | 外部 DSL | 程式語言中立的測試規格方式,使用自然語言語法 |
| Phoenix Routes | 內部 DSL | Elixir 的 Web 框架路由設施,將 HTTP 請求映射到程式碼中的處理函式 |
| Ansible | 外部 DSL | 使用 YAML 格式的規格來配置遠端伺服器的軟體 |
領域語言的特性#
RSpec 和 Phoenix 路由器是用宿主語言撰寫的(Ruby 和 Elixir)——它們是內部領域語言,嵌入在你執行的程式碼中,是你程式碼詞彙的真正擴展。
Cucumber 和 Ansible 配置是用它們自己的語言撰寫的——它們是外部領域語言,被程式碼讀取並轉換成程式碼可以使用的形式。
內部語言 vs 外部語言的取捨#
內部語言#
- 可以利用宿主語言的特性,更強大,且免費獲得這些能力
- 缺點是受限於宿主語言的語法和語義
- 支援巨集的語言(如 Elixir、Clojure、Crystal)給你更多彈性
外部語言#
- 沒有語法限制,只要你能寫解析器
- 寫解析器可能意味著需要新的函式庫和工具
- 可以使用 bison、ANTLR 或 PEG 解析器框架
務實建議#
- 不要花的工夫比你省下的多
- 一般來說,盡量使用現成的外部語言(如 YAML、JSON 或 CSV)
- 如果不行,考慮內部語言
- 只在語言會被應用程式的使用者撰寫時,才建議使用外部語言
低成本的內部領域語言#
如果你不介意宿主語言的語法洩漏出來,不需要做大量的元程式設計。只需寫函式來做工作。事實上,RSpec 基本上就是這樣做的——describe、it、expect、to、eq 只是 Ruby 方法。
相關章節#
- Topic 8,優秀設計的精髓
- Topic 13,原型和便利貼
- Topic 32,配置