DSL 問與答
2008 年 9 月 9 日
有人請我為非技術人員整理一份關於 DSL 的討論。也許我讀了太多 Stephen O'Grady 的文章,但我感到一股無法抗拒的衝動,想要以問答的方式來撰寫。因此,以下開始。
什麼是特定領域語言?
特定領域語言 (DSL) 是一種表達能力有限的電腦程式語言,專注於特定領域。您聽過的大多數語言都是通用語言,可以在軟體專案中處理您遇到的各種事項。每個 DSL 只可以處理系統的一個特定面向。所以您不會用 DSL 編寫整個專案嗎?
不會。大多數專案會使用一種通用語言和多種 DSL。它們是一個新想法嗎?
完全不是。自 Unix 系統的早期開始,DSL 就已在 Unix 圈廣泛使用。Lisp 社群經常討論在 Lisp 中建立 DSL,然後使用 DSL 來實作邏輯。大多數 IT 專案都使用多種 DSL - 您可能聽過 CSS、SQL、正規表示式等。那麼為什麼它們現在引起了很多討論?
可能是因為 Ruby 和 Rails。Ruby 作為一種語言,有許多功能可以輕鬆開發 DSL,而參與 Ruby 社群的人們已經從其他地方熟悉這種方法,因此他們利用了這些功能。特別是 Rails 使用了多種 DSL,在讓 Rails 如此易於使用方面發揮了重要作用。這反過來又鼓勵更多人採用這些想法。
另一個原因是許多 Java 和 C# 系統需要以更動態的方式定義其部分行為。這導致了難以理解的複雜 XML 檔案,這反過來又導致人們再次探索 DSL。
所以 DSL 可以用於 Ruby 以外的語言嗎?
是的,正如我所指出的,DSL 的存在時間遠遠早於 Ruby。Ruby 具有簡潔的語法和元程式設計功能,可以比 C# 和 Java 等語言更容易建立更優雅的內部 DSL。但在 Java 和 C# 中也有有用的內部 DSL。內部和外部 DSL 之間的區別是什麼?
內部 DSL 只是使用主機語言編寫程式碼的一種特定慣用語法。因此,Ruby 內部 DSL 是 Ruby 程式碼,只是使用特定風格編寫,提供更類似於語言的感覺。因此,它們通常稱為流暢介面或嵌入式 DSL。外部 DSL 是一種完全獨立的語言,可解析成主機語言可以理解的資料。為什麼人們對 DSL 感興趣?
我認為 DSL 有兩個主要優點。最常見的優點是它們讓某些類型的程式碼更容易理解,這使得修改程式碼變得容易許多,進而提升程式設計師的生產力。這本身就很有價值,而且相對容易達成。
然而,最有趣的優點是,設計良好的 DSL 可以讓業務人員理解,讓他們能夠直接理解實作其業務規則的程式碼。
所以這就是關鍵所在 - 業務人員自己撰寫規則?
一般來說,我不這麼認為。要建立一個讓業務人員撰寫自己規則的環境需要大量的工作。您必須建立一個舒適的編輯工具、除錯工具、測試工具等等。只要讓業務人員能夠閱讀規則,您就能獲得業務面對 DSL 的大部分好處。然後,他們可以檢閱規則的準確性,與開發人員討論規則,並起草變更供開發人員正確實作。讓 DSL 變得可供業務人員閱讀所需的努力遠低於讓業務人員撰寫規則,但卻能獲得大部分的好處。有時值得付出努力讓 DSL 可供業務人員撰寫,但這是一個更進階的目標。您需要特殊(即昂貴)的工具嗎?
一般來說,不需要。內部 DSL 只使用您無論如何都會使用的程式語言的常規功能。外部 DSL 確實需要您使用一些特殊工具 - 但這些工具是開源的,而且非常成熟。這些工具最大的問題在於,大多數開發人員不熟悉它們,而且認為它們比實際上更難使用(文件編寫不佳會讓這個問題更嚴重)。
然而,地平線上出現了例外。這些是我稱為語言工作台的一類工具。這些工具讓您能夠更輕鬆地定義 DSL,並為它們提供精密的編輯器。像這樣的工具讓建立可供業務人員撰寫的 DSL 變得更可行。
所以這是在重複軟體開發不需要程式設計(或程式設計師)的夢想嗎?
這是 COBOL 的意圖,我不認為有任何理由認為 DSL 會在 COBOL(以及許多其他失敗者)失敗的地方取得成功。我認為重要的是,DSL 允許業務人員和開發人員更有效地協作,因為他們可以討論一組共同的精確規則,這些規則是可執行的程式碼。我應該在什麼時候考慮建立 DSL?
當您在查看具有豐富業務規則或工作流程的系統層面時。一個寫得很好的 DSL 應該讓客戶了解系統運作的規則。這不會導致人們難以學習的語言大雜燴嗎?
我們已經有了程式設計師必須學習的框架大雜燴。這是可重複使用軟體的必然結果,這是我們唯一能處理軟體在當今必須做的事情的方法。從本質上來說,DSL 只不過是框架上的一個花哨外觀。因此,它們對已經存在的事物幾乎沒有增加複雜性。事實上,一個好的 DSL 應該通過讓這些框架更容易使用來讓事情變得更好。但人們不會建立許多糟糕的 DSL 嗎?
當然,就像人們建立糟糕的框架一樣。但同樣地,我認為糟糕的 DSL 與糟糕的框架的成本相比並沒有造成太多額外的損害。