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內部 DSLRuby 的測試庫,測試用來反映你期望程式碼的行為
Cucumber外部 DSL程式語言中立的測試規格方式,使用自然語言語法
Phoenix Routes內部 DSLElixir 的 Web 框架路由設施,將 HTTP 請求映射到程式碼中的處理函式
Ansible外部 DSL使用 YAML 格式的規格來配置遠端伺服器的軟體

領域語言的特性#

RSpec 和 Phoenix 路由器是用宿主語言撰寫的(Ruby 和 Elixir)——它們是內部領域語言,嵌入在你執行的程式碼中,是你程式碼詞彙的真正擴展。

Cucumber 和 Ansible 配置是用它們自己的語言撰寫的——它們是外部領域語言,被程式碼讀取並轉換成程式碼可以使用的形式。

內部語言 vs 外部語言的取捨#

內部語言#

  • 可以利用宿主語言的特性,更強大,且免費獲得這些能力
  • 缺點是受限於宿主語言的語法和語義
  • 支援巨集的語言(如 Elixir、Clojure、Crystal)給你更多彈性

外部語言#

  • 沒有語法限制,只要你能寫解析器
  • 寫解析器可能意味著需要新的函式庫和工具
  • 可以使用 bison、ANTLR 或 PEG 解析器框架

務實建議#

  • 不要花的工夫比你省下的多
  • 一般來說,盡量使用現成的外部語言(如 YAML、JSON 或 CSV)
  • 如果不行,考慮內部語言
  • 只在語言會被應用程式的使用者撰寫時,才建議使用外部語言

低成本的內部領域語言#

如果你不介意宿主語言的語法洩漏出來,不需要做大量的元程式設計。只需寫函式來做工作。事實上,RSpec 基本上就是這樣做的——describeitexpecttoeq 只是 Ruby 方法。

相關章節#

  • Topic 8,優秀設計的精髓
  • Topic 13,原型和便利貼
  • Topic 32,配置