上回寫了一點關於 Domain-Specific Languages(DSL)的粗淺概念,之後我又看了一些跟 domain-specific 有關的資料,主要是《Domain-Specific Development with Visual Studio DSL Tools》和《Domain-Specific Modeling》,所以這裡就個人的理解做點筆記,簡單介紹一下特定領域開發( Domain-Specific Development;DSD)和特定領域塑模( Domain-Specific Modeling;DSM)的概念。當然,目前還是停留在 scratching surface 的程度,離實作開發還很遠啦。
標準化與客製化
DSD 和 DSM 都是強調特定領域(domain-specific)的軟體設計方法,而且都是以 DSL 為其基本要素。所謂的特定領域開發或特定領域塑模,指的是針對特定問題領域--尤其是比較小的問題領域--來進行軟體系統的設計。進一步說,開發人員必須為特定領域定義一套語言(DSL),並使用該語言來塑模軟體,而且這裡的「塑模」還有另一層重要的涵義:產生程式碼。
可是,為什麼要強調特定領域?當我們在開發複雜的軟體系統時,不就已經是針對特定的問題領域來進行設計嗎?
是這樣沒錯,但我們往往只能 reuse 程式碼,而未能直接 reuse 設計時所建立的模型。也就是說,碰到一個類似之前開發過的系統時,大部分還是重新設計。雖然經驗再加上複製剪貼的工夫已經能夠加快開發速度,程式碼也逐漸累積可重複使用的框架和基礎元件,但這樣的 reuse 程度還是無法明顯提高生產力。那麼究竟生產力要提高到什麼程度才夠?《Domain-Specific Modeling》的作者認為,大約要有從組合語言跳到第三代語言(例如 C 語言)的明顯差距,這樣的生產力才算是大幅躍進。後面會概略說明 DSM 是基於什麼理論方法來達到這個目標。
模型不能重複使用的主要原因,自然是因為大部分的軟體系統都不會完全一樣,不過,跟我們使用的塑模語言也有些關係。目前軟體社群普遍接受的塑模語言是 UML,這套語言是以標準化的圖形記號來表達軟體系統的各種面向,目的在於方便溝通。語言標準化的好處,是一旦多數人熟悉之後,彼此的溝通比較容易。相對的,它的缺點就是不提供特定領域的術語,因此往往無法精確表達特定領域的概念,而必須採用一些擴充的語法,如 stereotypes、tagged values 等等。如此一來,要從 UML 模型直接產生程式碼就會碰到許多困難。如上一篇引用過的,Booch 在 MDA Journal 發表的一篇文章裡這麼說:
現在可以進入 DSD 了。
Domain-Specific Development
DSD 的一項特點是同中求異,其主要精神在於找出軟體系統中固定的部份以及容易變動的部份,並使用 DSL 來描述變動的部份;每當建置軟體系統時,就利用輔助工具將 DSL 模型轉換或轉譯成程式碼,再與固定的部份相結合,編譯成完整的系統。下面這張圖取自《Domain-Specific Development with Visual Studio DSL Tools》,它明白表達了上述概念:
所謂固定的部份(Fixed Part),指的就是手寫的程式碼,主要由軟體框架、模式(patterns)、以及一些共用元件所組成。整合(Integrate)的動作就是利用工具將模型轉換為程式碼,並與固定的部份相結合,最後再編譯為完整的應用程式。
其實這種概念四處可見,舉例來說,我們可以將個人電腦的主機板視為固定的部份,而主機板上面的 I/O 介面擴充槽、記憶體擴充槽、USB 連接埠等則是為了介接可變動的部分。假設有一種製造個人電腦的工廠,我們可能會開兩條生產線,一條專門生產高階工作站,使用的是高階顯示卡及高容量記憶體;另一條線則配接陽春的配備,生產價格較低廉的入門機種。
如果能夠將同類型的軟體系統之間的差異抓出來,並利用 DSL 工具加以自動化(產生程式碼),軟體生產線的理想境界或許終有實現的一天。
Domain-Specific Modeling
DSM 又比 DSD 更進一步(說更誇張或許比較貼切)。DSM 強調更完全的、更高層次的自動化,就像利用編譯器將程式碼編譯成可執行的軟體,當我們發現應用程式需要修改時,我們不會去改編譯過的二進位檔案,而是修改程式碼,然後重新編譯。DSM 的哲學也是如此:當我們發現設計出來的軟體有問題時,並不是直接修改程式碼,而是修改模型,然後利用工具將模型轉換成程式碼,再進行編譯。就像前面說的,《Domain-Specific Modeling》的作者認為,大概要有從組合語言跳到第三代語言(例如 C 語言)的明顯差距,生產力才算是大幅提升,而要達到這個目標,軟體系統的程式碼就必須完全從模型產生出來。下圖取自那 DSM 這本書的第一章,主要是展示 DSM 模型看起來長什麼樣子(圖形符號是自己定義的):
這張圖描繪的是研討會報名作業,圖中的方塊和箭頭等符號都不是單純的幾何圖形,它們都會對應到特定領域的概念及實作。我想,在能夠畫這些圖形符號之前,必定要費好大一番工夫,你至少得先定義 DSL、開發一套 DSL 塑模工具、還有程式碼產生器。此外,如果照 DSM 的作者說的,整個軟體系統的程式碼都是從模型產生出來,我很想知道當我把其中一個方塊的箭頭改指向另一個方塊會發生什麼事。
比 Hello World 再複雜一點的程式,或許可以做到完全透過模型來產生程式碼,對於許多複雜的商業軟體系統......我想我還需要更多想像力才行。相較之下,DSD 顯得實際多了。
註:就像 domain-specific languages 一樣,domain-specific modeling 並不是特定人或社群的專利;它只是強調特定領域的軟體設計理念和方法。這裡講的 DSM,指的都是《Domain-Specific Modeling》這本書所提的概念。
小結
DSD 和 DSM 的內涵雖然是軟體設計,但是從本文介紹的概念可以發現,它們也會影響軟體開發流程,因為塑模和產生程式碼的部份也在軟體開發過程中佔有很大的比重。除了簡單介紹 domain-specific design 的概念,文中也提到 UML/MDA 和 DSL/DSD/DSM 的基本差異。我想或許可以這麼說:UML/MDA 是以標準化為出發點,基本的理念是異中求同,先定義一套共通的語言,再利用它來表達各種系統的設計模型;DSL/DSD 則為同中求異,著重在塑模差異的部份,並將該部分的實作自動化,同時結合框架、模式、及工具來提升軟體開發的速度。
參考資料
標準化與客製化
DSD 和 DSM 都是強調特定領域(domain-specific)的軟體設計方法,而且都是以 DSL 為其基本要素。所謂的特定領域開發或特定領域塑模,指的是針對特定問題領域--尤其是比較小的問題領域--來進行軟體系統的設計。進一步說,開發人員必須為特定領域定義一套語言(DSL),並使用該語言來塑模軟體,而且這裡的「塑模」還有另一層重要的涵義:產生程式碼。
可是,為什麼要強調特定領域?當我們在開發複雜的軟體系統時,不就已經是針對特定的問題領域來進行設計嗎?
是這樣沒錯,但我們往往只能 reuse 程式碼,而未能直接 reuse 設計時所建立的模型。也就是說,碰到一個類似之前開發過的系統時,大部分還是重新設計。雖然經驗再加上複製剪貼的工夫已經能夠加快開發速度,程式碼也逐漸累積可重複使用的框架和基礎元件,但這樣的 reuse 程度還是無法明顯提高生產力。那麼究竟生產力要提高到什麼程度才夠?《Domain-Specific Modeling》的作者認為,大約要有從組合語言跳到第三代語言(例如 C 語言)的明顯差距,這樣的生產力才算是大幅躍進。後面會概略說明 DSM 是基於什麼理論方法來達到這個目標。
模型不能重複使用的主要原因,自然是因為大部分的軟體系統都不會完全一樣,不過,跟我們使用的塑模語言也有些關係。目前軟體社群普遍接受的塑模語言是 UML,這套語言是以標準化的圖形記號來表達軟體系統的各種面向,目的在於方便溝通。語言標準化的好處,是一旦多數人熟悉之後,彼此的溝通比較容易。相對的,它的缺點就是不提供特定領域的術語,因此往往無法精確表達特定領域的概念,而必須採用一些擴充的語法,如 stereotypes、tagged values 等等。如此一來,要從 UML 模型直接產生程式碼就會碰到許多困難。如上一篇引用過的,Booch 在 MDA Journal 發表的一篇文章裡這麼說:
「唯有當塑模的概念能夠直接對應到領域概念,而非電腦技術的概念,MDA 方能展現其完整價值。」
(The full value of MDA is only achieved when the modeling concepts map directly to domain concepts rather than computer technology concepts.)
現在可以進入 DSD 了。
Domain-Specific Development
DSD 的一項特點是同中求異,其主要精神在於找出軟體系統中固定的部份以及容易變動的部份,並使用 DSL 來描述變動的部份;每當建置軟體系統時,就利用輔助工具將 DSL 模型轉換或轉譯成程式碼,再與固定的部份相結合,編譯成完整的系統。下面這張圖取自《Domain-Specific Development with Visual Studio DSL Tools》,它明白表達了上述概念:
所謂固定的部份(Fixed Part),指的就是手寫的程式碼,主要由軟體框架、模式(patterns)、以及一些共用元件所組成。整合(Integrate)的動作就是利用工具將模型轉換為程式碼,並與固定的部份相結合,最後再編譯為完整的應用程式。
其實這種概念四處可見,舉例來說,我們可以將個人電腦的主機板視為固定的部份,而主機板上面的 I/O 介面擴充槽、記憶體擴充槽、USB 連接埠等則是為了介接可變動的部分。假設有一種製造個人電腦的工廠,我們可能會開兩條生產線,一條專門生產高階工作站,使用的是高階顯示卡及高容量記憶體;另一條線則配接陽春的配備,生產價格較低廉的入門機種。
如果能夠將同類型的軟體系統之間的差異抓出來,並利用 DSL 工具加以自動化(產生程式碼),軟體生產線的理想境界或許終有實現的一天。
Domain-Specific Modeling
DSM 又比 DSD 更進一步(說更誇張或許比較貼切)。DSM 強調更完全的、更高層次的自動化,就像利用編譯器將程式碼編譯成可執行的軟體,當我們發現應用程式需要修改時,我們不會去改編譯過的二進位檔案,而是修改程式碼,然後重新編譯。DSM 的哲學也是如此:當我們發現設計出來的軟體有問題時,並不是直接修改程式碼,而是修改模型,然後利用工具將模型轉換成程式碼,再進行編譯。就像前面說的,《Domain-Specific Modeling》的作者認為,大概要有從組合語言跳到第三代語言(例如 C 語言)的明顯差距,生產力才算是大幅提升,而要達到這個目標,軟體系統的程式碼就必須完全從模型產生出來。下圖取自那 DSM 這本書的第一章,主要是展示 DSM 模型看起來長什麼樣子(圖形符號是自己定義的):
這張圖描繪的是研討會報名作業,圖中的方塊和箭頭等符號都不是單純的幾何圖形,它們都會對應到特定領域的概念及實作。我想,在能夠畫這些圖形符號之前,必定要費好大一番工夫,你至少得先定義 DSL、開發一套 DSL 塑模工具、還有程式碼產生器。此外,如果照 DSM 的作者說的,整個軟體系統的程式碼都是從模型產生出來,我很想知道當我把其中一個方塊的箭頭改指向另一個方塊會發生什麼事。
比 Hello World 再複雜一點的程式,或許可以做到完全透過模型來產生程式碼,對於許多複雜的商業軟體系統......我想我還需要更多想像力才行。相較之下,DSD 顯得實際多了。
註:就像 domain-specific languages 一樣,domain-specific modeling 並不是特定人或社群的專利;它只是強調特定領域的軟體設計理念和方法。這裡講的 DSM,指的都是《Domain-Specific Modeling》這本書所提的概念。
小結
DSD 和 DSM 的內涵雖然是軟體設計,但是從本文介紹的概念可以發現,它們也會影響軟體開發流程,因為塑模和產生程式碼的部份也在軟體開發過程中佔有很大的比重。除了簡單介紹 domain-specific design 的概念,文中也提到 UML/MDA 和 DSL/DSD/DSM 的基本差異。我想或許可以這麼說:UML/MDA 是以標準化為出發點,基本的理念是異中求同,先定義一套共通的語言,再利用它來表達各種系統的設計模型;DSL/DSD 則為同中求異,著重在塑模差異的部份,並將該部分的實作自動化,同時結合框架、模式、及工具來提升軟體開發的速度。
參考資料
- Domain-Specific Development with Visual Studio DSL Tools
by Steve Cook, Gareth Jones, Stuart Kent, and Alan Cameon Wills. Addison Wesley, 2007. - Domain-Specific Modeling: Enabling Full Code Generation
by Steven Kelly, Juha-Pekka Tolvanen. Wiley-IEEE Computer Society Pr (March 7, 2008) - Domain-Specific Modeling
by Steve Cook. The Architecture Journal, October 2006. - Domain-Specific Modeling with METAEDIT: 10 Times Faster Than UML
by MetaCase, 2007.
沒有留言: