[翻譯] DSL和模型驅動開發的最佳實踐(1/4)
1 引言
這篇文章我將介紹多年來我使用DSL進行軟件開發的最佳實踐,在開始之前,我先概述一下內容。我專門針對自定義描述軟件系統的領域特定語言,這些語言可以是文本的也可以是圖形的,創建的模型再由代碼生成,驗證,模擬和解釋使用,DSL是為開發人員和架構人員使用的(主要包括軟件系統的架構/技術方面),同時也可以被那些通常不被稱為開發者的商業用戶使用。
我明確排除內置/嵌入式的DSL, 比如由Ruby,Coverge或者Lisp構建的DSL, 當然也不考慮MPS(譯注:Jetbrains開發的,我在這里有介紹)這種通過擴展一個圖靈完備的語言構建的DSL。
這篇文章是最佳實踐的一些高度概括。對于他們其中的每一個,我都可以寫很多頁(實際上確實也是,已經有了很多關于這些或者其它實踐的內容,見[1,2,3])。 盡管內容簡單,這篇文章還是會提醒你當考慮MD*你的項目時應該考慮的所有的事情。
關于術語的注意事項:
使用MD*作為MDD,MDSD,MDE,MDA,MIC和其它原理相同的方法名詞的縮寫。
模型可以通過很多種方式處理,可以被驗證,轉換,生成代碼或者解釋。采用“模型處理(model processing)”(名詞是模型處理器model processor)這個術語來代表所有的這些。
使用術語”元數據(metaware)”來指所有的元數據級別的物件。元數據包括DSL,元模型,編輯器,模型處理。
通常一個描述系統的全面的模型分成許多“模型單元(model units)”,我稱之為分區partitions(例如XML文件)。
采用術語”業務應用business”,來指示所有應用領域,可以是科學,機械,自動化,金融或者保險,而不是具體的財務/會計/法律這些業務,這個詞主要用來與程序員/設計師/分析師處理的程序/軟件區分。
每一個最佳實踐都評定了星級,數據來源于我在同事當中做的一個小調查。到現在為止,只有10個人回復了,所以這個調查不一定有代表性,但是它肯定是最佳實踐的一個指示:
我并不認為是這樣,我經常使用一種技術與之相矛盾
我沒有使用過,但是它聽起來有道理,我想如果當我必須要面對這樣的問題的時候我會這樣來做
我成功的使用過,但是我不肯定這是通用的最佳實踐
我成功的使用過很多次,我確信這是最佳做法,不用才怪呢
文章有三個主要部分:
第1部分: DSL的設計,設計你的語言時一定要銘記的最佳實踐。
第2部分: 模型處理,模型檢查,解釋和代碼生成。
第3部分: 考慮你必須記住的有關過程和組織方面的事情。
第4部分: 著眼于MD*世界里面臨的問題和挑戰.
2 設計DSL
領域特定語言的語言來源
如何能夠挖掘出你的DSL表示什么?如何來進行抽象,以及對應的符號是什么?這不是一個普通問題,事實是這是MD*里最主要的問題,這需要大量的經驗和思考以及不斷的迭代。不過也有一些典型的方法:
如果你在構建一個技術型的DSL,語言的來源通常是一個已經存在的框架Framework,類庫library,架構architecture或者是架構模式architecture pattern,這方面的知識通常是你已經具備了的,構建DSL主要是形式化這些知識:定義表示方式,用格式化的語言表達出來,并且構建生成器生成部分實現代碼,在這過程中,經常會將框架的一些功能特征當成合理的潛規則(默認規則),這能夠提高框架的抽象層次,使框架更容易使用。
如果你在構建一個業務領域DSL, 你需要收集領域專家現有的知識,在保險,科學,后勤這些領域,專家們絕對有能力很好地表達相關知識.他們一直做這方面,經常使用Excel或者Word.他們有自己的”語言”來表達領域概念,雖然可能并不是規范的語言,并且沒有工具支持。在這種情況下,你的工作就是提供這種規范格式和工具,除了領域知識,其它的東西也是可以利用的:比如硬件結構或者設備特征在個別領域也是不錯的選擇。
在以上兩個領域,我們對DSL的期望很明確,只需要注意一些細節,表示形式,規范化,視點(ViewPoints),喜好(這些也是很重要的)。不過在其它的情況下我們就沒有這么幸運了,如果沒有現成的領域知識,我們必須去做一個領域分析,利用已有的應用,從需求出發,參與其中。
對于你的第一個DSL,嘗試找到一兩個案例,理想的情況是從第一個案例開始,因為構建DSL和支持工具的人往往就是領域專家或者軟件架構師和開發者.
極根表現力
當構建DSL的時候,確認你沒有被誘惑到構建又一個圖靈完備的通用語言,其實在許多情況下,僅僅一個聲明式的語言就足以表述一個系統了。
注意配置和定制之間的差異,一個可定制的DSL提供了足夠的詞匯量,讓你能夠創造性的組合成任意復雜的句子,可配置的DSL由明確的參數組成,用戶可以直接指定參數的值(例如特征模型)。當然配置型DSL是比較有限的,因為實例以及事物之間的關系并不能夠很容易的表達,然而它們并不是很復雜,你越是向配置方面傾斜,一般構建模型處理就越容易,對于用戶來講,也就更容易使用,因為它的表面的復雜性是有限的。
請注意精確性和算法完整之間的不同,許多領域專家能夠正規的精確的定義他們的領域里的東西(即這個領域是什么),但是他們不能夠定義算法來實現系統,但是作為開發者來說,你的工作就是提供一種形式語言來給領域專家用于表述事實,然后實現生成器和解析器來把這些事實映射為可執行的算法(要和它們表述的知識保持正確),DSL表述了“什么”,而模型處理器添加了“如何”。
如果需要關注你的系統由哪個3GL語言來抽象(例如,你需要一個圖靈完備的強大的表達能力,而不用比較大的語義擴展),嘗試定義一個DSL來實現這個并不是一個好的注意。定義或者生成一個API,來讓開發者直接用3GL寫代碼, 你可以在生成的代碼里直接生成掛鉤,讓開發者可以直接用3GL代碼實現一些特殊的功能,保持掛鉤的目的性一定要明確,其數量一定要有限!
符號,符號,符號
構建DSL的時候,表現符號是相當重要的。作為語言設計者,你關心的可能多半是基本的元數據模型,可能并不真正的關心”漂亮的語法”, 但是從領域用戶的角度來看,情況可能正好相反。
特別是在業務領域(但不限于),要想成功,你必須調整你的表現方式來適應這個領域(甚至是這個領域已經存在的表現方式)。試圖勸服他們來使用一個“更好的表現方式”往往會讓你失望,只要實現他們有的就行了。
注意這可能需要文本或者圖形符號,類似于Excel電子表格,表單系統或者他們的混合,現在的DSL工具在這方面有限制。不過我相信在今后幾年DSL工具的演變中將主要解決這個問題。到現在為止,你只需要考慮到表現符號的易變性,盡最大努力開發可用的工具。
表現符號應該使通用的東西表達起來簡明,能夠提供一些合理的缺省規則,即使少數需要額外的修飾來實現也是允許的。
當勾畫DSL定義原型的時候,從表現方式開始,與使用者直接交叉檢查是很有用的。
圖形 vs 文本符號
是不是圖形描述的比文本描述的更容易理解呢? 其實不然。就易理解性來說最重要的就是把需要用語言抽象轉達的概念排列,一個設計好的文本符號更加持久耐用,當然,對于一些特定類型的信息,圖形符號是更好的選擇:實體之間的關系,一些事件或者信號/數據流的時序/順序。相反,用圖形展現公式是一條走不通的死路(附注:圖形公式編輯器在某種程度上是與顯示分數,矩陣,積分等方式的混合體)。
在談到決定一個合適的符號時,你可能需要考慮以下兩個因素:大多數(但不是全部)工具環境,相對于比用戶友好可擴展的圖形編輯器來說,文本符號的編輯器(包括代碼完成,語法高亮等)更容易構建和演變,文本符號還更容易與源代碼管理和build機制集成。
此外,代替使用全面的圖形編輯,你可能會考慮文本編輯+可視化圖形(見下文)。
在使用圖形編輯器的環境中需要做很多工作,我建議首先使用簡單的文本編輯器(文本,樹,通常的框/線)來穩定語言的概念和抽象,然后再投入開發一個完美的圖形化編輯器。
在許多系統中,一些觀點是支持圖形編輯器,其它的是文本。有時候你甚至想混合這兩種方式: 狀態機(圖形符號)其中的斷言表達式(文本符號),但是這對于現在的工作來說比較棘手。
語義DSL(未評級)
只為DSL定義抽象和表現符號還是不夠的,你還必須定義抽象的意義--語言的語義。
在某種意義上,一個語言的語義比使用這個語言表達需要更多的這個領域的知識:語言允許用戶使用模型僅僅表達針對于某一特定 系統/應用/案例。然后語義需要這個領域每一個 系統/應用/案例 之間所有相同的東西。
從技術上講,這是生成器,解析器的工作,平臺使他們聯系起來,然而從語言使用者的角度來說(他們并不知道什么是模型處理器),語義是隱性知識“語言是如何工作的”,而它必須解釋為“語言的意義”.
有許多種正式地定義語義的方式,但是沒有任何一個在主流DSL實踐中是足夠實用的(到2008年), 因為一種語言的含義在兩個方面來定義:用短文來解釋,用例子用于語言使用者,并且直接向下通過代碼生成器或者解析器和可執行平臺綁定在一起。(嚴格意義上講,這是業務語義的定義,因為生成器映射語言概念到已經存在語義的目標語言概念)
原文: Best Practices for DSLs and Model-Driven Development
由于篇幅太長,所以分幾部分翻譯。翻譯水平有限,如果英語不錯,最好直接閱讀原文.
向模型驅動開發的同學們強烈推薦此文!
作者:孤獨俠客(似水流年)
出處:http://lonely7345.cnblogs.com/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。

浙公網安備 33010602011771號