Michael Hunger
什麼是 DSL#
當你聽專家討論任何領域——無論是棋手、幼兒園老師還是保險代理人——你會注意到他們的詞彙和日常語言截然不同。這就是**領域特定語言(Domain-Specific Languages, DSLs)**的核心:一個特定領域擁有一套專門的詞彙來描述該領域特有的事物。
在軟體世界中,DSL 是關於將可執行的表達式寫成一種針對特定領域的語言,採用有限的詞彙和文法,可讀、可理解,並且——希望——可以由領域專家撰寫。Unix 的「小語言」和 LISP 巨集是較早的範例。
內部 DSL(Internal DSLs)#
內部 DSL 是用通用程式語言撰寫的,但語法被調整得更像自然語言。這在提供更多語法糖和格式化可能性的語言中更容易實現(例如 Ruby 和 Scala),對其他語言(如 Java)則困難一些。
大多數內部 DSL 封裝現有的 API、函式庫或商業邏輯程式碼,提供一個包裝層,讓非專家也能直接執行。根據實作和領域的不同,它們可以用於:
- 建構資料結構
- 定義依賴關係
- 執行流程或任務
- 與其他系統溝通
- 驗證使用者輸入
內部 DSL 的語法受限於宿主語言。常見的模式包括 expression builder、method chaining 和 annotation 等。如果宿主語言不需要重新編譯,內部 DSL 可以很快地與領域專家並肩開發。
外部 DSL(External DSLs)#
外部 DSL 是語言的文字或圖形表達式——雖然文字型 DSL 比圖形型更常見。文字表達式可以由包含 lexer、parser、model transformer、generator 等工具鏈處理。外部 DSL 大多被讀取為內部模型,作為進一步處理的基礎。
定義文法時使用 EBNF 等符號是有幫助的。文法為工具鏈的生成提供起點(如編輯器、視覺化工具、parser generator)。對於簡單的 DSL,手工 parser 可能就夠了——例如使用正規表達式。專門用於語言文法和 DSL 的工具包括 openArchitectureWare、ANTLR、SableCC、AndroMDA 等。
將外部 DSL 定義為 XML 方言也很常見,但可讀性往往是個問題——尤其對非技術人員來說。
考量目標受眾#
在設計 DSL 時,你必須考慮目標受眾——他們是開發者、經理、業務客戶還是終端使用者?你需要根據受眾的技術水準來調整語言、可用工具、語法協助(如 IntelliSense)、早期驗證、視覺化和呈現方式。
透過隱藏技術細節,DSL 可以賦予使用者能力,讓他們不需要開發者的幫助就能根據需求調整系統。在初始語言框架建立之後,DSL 也能加速開發,因為工作可以分配給更多人。語言可以逐步演進,現有的表達式和文法也有不同的遷移路徑可用。