HOME 回資訊服務處首頁 Login
2006年第3期
簡訊
PNC 2006年韓國年會暨PRDLA、ECAI聯合會議8/15-18舉行
本院台北GigaPoP光纖纜線忠孝東路段將於8月上旬完成遷移
完成本院環變中心新辦公室網路建置
網路影音服務新增兩項視訊內容
資訊活動訊息--「台北電腦應用展」8/3-7世貿一館展出
資訊安全
個人電腦安全之防護
資訊話題
細說「軟體工廠」概念(十五)
 
資訊話題 >
上一篇 | 返回電子報
 
細說「軟體工廠」概念(十五)
 
吳信輝

(文續第2006年第2期)

設計樣式語言封裝(Encapsulating Pattern Languages)

1.什麼是封裝?

 封裝(Encapsulation),這一個名詞,在筆者的概念裡面,應該比較偏向包裝的意思,雖然在『軟體工廠』一書以及一般字典裡面的解釋之中,封裝的主要概念是:將不必要的細節給隱藏起來,但是筆者比較喜歡偏向包裝的意思;不過,有關於這一點的概念,則是見仁見智了。『軟體工廠』一書對於封裝的解釋是:「將不必要的細節給隱藏起來」。這一個解釋又好像有點類似先前提過的抽象化(abstraction),因此在這裡,我們需要針對這一點重新做解釋。針對封裝這一個名詞,該書中的內容是做了這樣的解釋:「封裝把一些細節給忽略,並利用另一套新的詞彙來表示」

 以先前在文章中所提過的,一個城市的大眾運輸系統的網路圖為例,除了捷運路線的簡化是抽象化的代表之外,公車的路線圖則是利用了封裝這一個概念,回顧一下『軟體工廠』一書的解釋:封裝將某些細節給忽略,並利用另外的語彙來解釋。公車路線圖的內容,公車路線名稱、公車停靠站名稱,都是利用封裝的概念產生的。因為如果我們用道路的名稱來表示某條公車路線的話,將讓使該公車路線名稱變的非常冗長,所以一般的公車路線名稱都是利用代號的方式,例如:101-內湖。最近我們可以看到台北的捷運接駁公車路線,就變得更加簡潔;而公車路線上的每一個停靠站則是該停靠站區域的簡稱,或是代表性名稱,例如:台大醫院站等。所以,我們可以看到經過封裝這一個動作,公車路線被重新定義了,包括公車路線中的字彙;另外經過封裝這一個動作,我們也可以針對被封裝的對象,定義其新字彙間的文法。簡單地說,就是我們利用另外一種方式、語彙文法來表達原本複雜的東西,這與抽象化單純的簡化的概念是不相同的。以上是該書
對於封裝的基本解釋。

 而筆者將封裝比喻成包裝的感覺,也是類似這樣的概念。一個喜餅如果沒有經過包裝,我們只會認為他是一般的餅而已;如果經過包裝之後,我們對於它是喜餅的感覺就會增加,原本是屬於一般餅的細節被忽略掉,它被重新定義為喜事用的餅。經過以上的說明,我們可以將封裝解釋為:「忽略不重要的細節、描述,將原本要表達的資訊壓縮為一組與原來的字彙不同的新字彙,並利用另外一套簡潔的方式來表達需要的概念」。

2.定義封裝語言(Defining Language with Encapsulation)

 依據Cleaveland的觀察【註1】,他認為封裝將軟體開發區分為兩個部份,第一部份是軟體規格(specification),第二部份是軟體實作(implementation)。軟體規格定義了軟體中應該存在的元素,但是並沒有告訴我們該如何做。軟體實作則是將軟體規格中所描述的內容實作出來,軟體實作提供了軟體規格中所描述的如何做的知識。就如同我們先前提過的公車路線圖,如果我們要利用公車路線圖來進行我們的旅遊計畫,例如:從101到台北車站的旅遊計畫,我們可以利用公車站牌來做為我們每一個中途停站點的資訊,在我們的腦子之中,公車站牌就會自動映對成實際的道路街名或是該街墎。

 經由這樣的方式,我們可以用比較簡潔以及比較有效率的描述方式來表達。也就是說,軟體規格是比軟體實作更為抽象化的一種描述,軟體規格所忽略的細節正式軟體實作中的細節。軟體規格也是一種比較通用型的描述,利用通用型的描述來表示軟體規格有什麼好處呢?一般來說,我們會說軟體的實作會是比較客製化的,經過客製化後的產品通常是不容易更改、變動的;而用通用性的描述可以讓我們有比較多的彈性存在,就好像我們依據我們的公車路線旅遊計畫來走,如果從A地到B地,公車路線在實際狀況中,可能就會有不同的實際行走路線。也就是說,軟體規格並沒有辦法被直接被實作出來,為了要完成軟體規格所描述的內容,我們必須藉著轉換(translate)將軟體規格變成實作。所以換句話說,封裝就是將軟體規格中的如何分離出來,以及擷取藉由轉換過程中所獲得的重用經驗,變成實作資訊。

 不過在此我們可能會產生一個問題,那就是:為何要另外產生一套語言?筆者簡單地說明如下:「因為一般的程式語言的目的是在操縱電腦,雖然我們在程式語言的內容之中用了許多我們人類的語彙,但是這些語彙大多是邏輯的陳述,與我們一般的概念與語言的邏輯還是不大一樣;軟體規格可以提供比實作更有效率的描述,這效率就是為何我們需要另外產生的一組語言的原因。這一組語言,我們通常稱之為描述軟體規格語言」。最近流行的描述性語言(script language)就是一個很明顯的例子,或許它沒有一般的程式語言的嚴謹度,但是在使用上卻是符合我們的直覺想法,這也是為何流行的原因。

 依據該書中的內容說明,描述軟體規格語言,注重的是效率(efficiency);效率的另外一個同義詞就是power。有關於power這一個名詞,使用中文解釋,例如:力量、威力,可能不大合適,所以筆者只用原文來表示。更有效率的軟體規格描述語言也就代表更有powerful;有效率的語言可以描述更為特定的邏輯與內容,就像我們的公車路線一樣。台北市以前曾經推動過文化公車路線,文化公車路線的內容對於想探訪台北市文化古蹟的人是非常有用的,但是對於一般人來說,效用就不大。就像一般的街道圖,目的是一般化的,可以運用的範圍也比較廣大,但是要針對某些特定目的的使用來說,就比較沒有效率了。依據上面的說明,我們可以歸納出下列的特點:「一個有效率的語言可以在相同的表達模式中間傳達更多的資訊,一個更powerful的軟體語言可以支援更有效率的溝通,達成更多期望的目的」

 從上面的說明,我們可以瞭解為何要定義封裝語言,因為我們無法只用一個語言,就可以從需求轉換成解決方案,從軟體規格變成軟體實作。所以,我們需要另外一組語言來描述,這就是定義封裝語言的原因。

3.正規化設計樣式語言(Formalizing Pattern Language)

 首先我們來解釋formalize這一個動詞的意思,formalize的中文意思是正規化、模式化或是公式化,在此我們採用第一個中文解釋應用在後續的內容中。

(1) 為何要正規化設計樣式語言呢?

 定義了封裝語言之後,我們為了要有一個共通的標準,所以我們需要將封裝的語言給正規化。在上一期的內容之中,我們曾經提過樣式(pattern)的名字就是組成樣式語言的摘要;而且『軟體工廠』一書的作者也曾經暗示我們,一個正規語言是藉著封裝樣式的規格而定義出來的,所以我們可以先回想一下,我們曾經提過,封裝的目的就是產先一組新的描述(軟體規格)來取代實作的描述,我們也曾經提過軟體規格是利用一組新的語言來描述,這一組新的語言的組程式經由封裝的程序流程而完成,而這一組新的語言可以與原先進行實作的語言產生映對(mapping),這也是為何我們產生這一組語言的目的。因此,我們可以在由樣式語言所定義的抽象化的基礎上,利用封裝產生一組新的正規化語言。例如:我們不要利用標準的J2EE Design Pattern Language來達成與Java原始碼的映對,我們利用中間一層的正規化語言,像是某某controller、某某View Dispatcher、某某Business Delegate、某某Session Facade和某某Service Locator等等。利用這樣的語言,利用這些抽象化的樣式,我們可以將一個以J2EE為基礎的應用系統明確地制訂、實作出來。利用這一種方式所產生的軟體應用系統架構,是可以被實用於我們產生的軟體規格之中。

(2) 正規化語言的好處

 將軟體規格語言的好處有什麼呢?正規化軟體規格語言除了有一個共同的標準可以遵循這一個好處之外,第二個好處,依據『軟體工廠』一書中的內容:「這樣的架構是很容易被修改的,也許只需要改變應用系統的樣式就可以適應設計上的改變,或是選擇對於樣式的不同實作策略就可以滿足需求上的改變,或是滿足未來新系統可能遭遇狀況的假設」。換句話說,第二個好處就是利用正規化語言的優勢就是彈性,不管以後程式語言的變動,或是應用程式架構的變動,我們都可以依據其變動的原因做出彈性的調整。

  以上應用正規化語言的兩個好處,並不是應用了就馬上會直接獲得這樣的好處。應用正規化語言的重點在於:「從正規化語言到Java等程式語言原始碼的映對,必須由樣式語言來提供,也就是說這些樣式語言必須提供足夠的資訊來進行實作,提供從軟體規格轉換到實作的相關資訊」。如果沒有這些資訊,那麼我們使用正規化語言就沒有優勢存在了,反而會徒增困擾。

  經過以上的說明,為何需要正規化軟體規格語言呢?其實提供正規化的軟體規格語言的目的很簡單,就是為了要完成軟體規格與實作之間的中間階段的銜接,也就是強化模式語言的功能【註2】。

什麼是模式?

  首先,我們先引用『軟體工廠』一書中的內容:「模式語言就是用來建造模式用的(Modeling language are used to build models)」。為了要完全的瞭解模式語言,我們必須先瞭解什麼是模式。雖然該書在先前已經多次提到模式這一個名詞,但是都沒有明確地定義模式的概念為何?在此,我們也是先用一些比較不正式的定義來描述模式。請接著觀看以下的內容,希望經由這一些非正式的定義的說明之後,我們可以對模式有更加一步的瞭解。

1. 模式就是抽象化(Models as Abstractions)

 還記得『軟體工廠』一書在先前的針對模式的說明嗎?它說:「模式就是軟體的抽象化的描述。隱藏某些軟體的觀點、面向的資訊,將其他沒有被隱藏的觀點、面向的資訊簡單地表現出來」。因此模式可以利用統一樣式語言(UML)中的物件圖就描述出來,例如一個簡單的付款系統,如【圖1】所示。

 
圖1  一個Business entity model的範例圖資料來源:【註3】

 付款系統的物件圖只是簡單地描述了這一個系統擁有那些軟體物件,以及這些軟體物件間的相互關係。這是屬於一般化的描述,所以我們在實作的時候並不會侷限於必須利用那一種程式語言,這也是模式的優點之一。

 另外,我們可以回想一下:軟體的抽象化是將軟體的概念給區分為不同的觀點、面向來處理。所以,模式可以將軟體應用系統中的資訊區隔出來,有些模式可能是描述他的物件的架構,而有些模式可能是描述介面操作的流程,例如:business model、user interface model等。有關於利用不同的模式呈現一個軟體應用系統的全貌的細節內容,將於後續內容中作詳細說明。

2. 模式的可視化(Model Visualization)

 通常來說,我們讀了統一樣式語言的內容之後,我們會把模式認為就是一種利用圖形表示的方法而已,其實模式的表示方式並不侷限於圖形表示法而已。雖然說圖形表示的方法對我們而言,是比較容易理解的,但是圖形表示的方法在實際應用上來說,還是有其不足的地方。因此,模式常常利用文字的模式來協助模式內容的相關說明,例如:屬性等。該書中提到對於模式理解的重點在於:「我們必須瞭解到,明確分辨出由模式中所得出的詮釋資料(metadata)與詮釋資料的可視化是不一樣的」。

 圖形的可視化並不需要將綱要性的內容附載於圖上,而且圖形表示的方法,也不可能完全記錄所有的綱要資訊,這一點是我們必須要瞭解的,這就是圖形表示方法的缺陷。因此,就像我們剛剛所說的,我們可以利用很多不同觀點、面向的模式去表達一個軟體應用系統。

 同理而言,一個模式的內容,我們也可以利用很多不同的方式來表示,例如:目前的都很成熟的開發工具,利用了可視化的使用者介面,並包裝成了相關的的積木模組(widget),例如:精靈(wizard)、對話框(dialogue)、表單(form)與編輯器(editor)等。所以,有關於模式的詮釋資料,可以說是種類繁多、內容繁雜的;也因為這樣的特性,軟體開發人員本身要去維護,也是一項困難的任務。這一類比較簡單的、可以利用程式處理的工作,在目前軟體開發的發展流程中,都會想要利用自動化開發來完成。也因此,模式中有關於詮釋資料的相關紀錄,因為是記錄在文字介面的檔案之中,將可以讓我們利用工具程式去讀取相關的資訊,進行判別與動作,進而達成軟體的自動化開發的目標。

3. 模式就是詮釋資料(Models as Metadata)

 就像我們剛剛提過的,我們必須明確分辨出由模式所擷取出來的資訊與資訊的可視化差異。因為軟體工廠可以實用的關鍵因素在於軟體工廠是依據在模式的基礎上的,利用模式所提供的相關資訊,軟體工廠才可以在不同的觀點、面向上進行自動化的工作。就好像我們一般在寫程式的時候,也需要對我們程式碼進行註解一樣。一個正式的模式是一個可以擷取由人類或是利用軟體工具所產生的詮釋資料的階段性成品、成果。例如:Web Services的標準中的WSDL檔案【註4】。

4. 模式就是軟體發展的階段性成品、成果(Models as Development Artifacts)

 對於詮釋資料於自動化發展的更進一步或是更廣泛的應用是,快速應用軟體發展(rapid application development, RAD)的品質證明(hallmark)。快速應用軟體發展的工具就是基於正式的模式而產生的,但是這些工具並不是完全用來維持一個已經存在的模式,這些工具建立模式的方式是藉由從軟體發展的階段性成品、成果中擷取相關的資訊,例如:從原始碼的檔案中,利用這些資訊轉變成自動化發展的基礎。但是有些部份軟體快速發展工具仍然需要去維護一些存在的模式,例如:相關的設定檔、製造軟體的操作手冊,以及相關的專案檔案等,這些部份需要被維護,大多是因為這些檔案無法從其他的軟體發展階段性成品、成果中被擷取出來。

  接下來我們來討論這些無法自動擷取資訊所產生的問題。

(1) 模式的分割(Model Partitioning)

 模式如果要可以做為軟體的階段性成品、成果的話,就是要將模式的表達內容,利用檔案的方式呈現出來,如此一來,才可以讓軟體開發工具容易存取,進而達成自動化的目標。一個UML的模式所涵蓋的範圍就是一整個系統,所以一個模式傾向於將模式的描述區分為不同的檔案;但是如何分割,在目前並沒有一個共通的標準或是定論,因此,依據書中的描述是:「希望的模式是一個經過良好的組成的流程或編輯單元(a well-formed unit of processing or compilation)」

(2) 模式的參照(Model References)

 既然同一個模式區分為不同的檔案,也就是代表:一個模式中的元素一定要可以與另外模式中的元素進行參照(refer);但是模式之中如何進行參照,在程式語言中已經有這樣的例子。以JSP應用JavaBean為例,我們利用JavaBean來模擬軟體的元件,並且在JSP的頁面程式中宣告我們引用這一個JavaBean,然後頁面程式就會自動地進行參照。所以說,利用程式語言這樣的特性,在軟體原始碼中間,利用以名稱為基礎的參照方式來達成參照的目的。那麼,在模式的敘述上面,我們也可以利用XML檔案的描述方式來進行對於模式的參照的描述。要達成這樣的目標,我們必須進行下列幾項動作:

  • 每一個模式的元素必須要有一個名稱;
  • 每一個模式元素必須定義在名稱空間(namespace)下的範圍(scope)之中;
  • 每一個模式元素必須在其內容中存在一個可以完成經過驗證的名稱,這一個名稱是可以給其他模式參照的時候解析用的。

  以上就是簡單的模式參照的解決方案。

(3) 模式的版本(Model Versions)

 在知道如何有效分割模式,將模式存放在檔案中,並且解決、維護不同檔案間的相互參照問題之後,我們也必須知道,如何有效地管理模式的版本,以利我們在團隊工作時可以有效率的進行軟體開發,以下有幾個我們必須考量的議題:

 第一個議題就是模式的相容性,我們應該如何判斷模式前後版本的差異,在模式中處理的模式的相容性有幾個方法:

  • 直接在模式名稱上依據模式版本來命名;
  • 加入一些地區化的因素考量,例如:英文版與簡體中文版等;
  • 加入其他相容性內容的說明。

 第二個議題就是我們在參照模式時,可以正確地參照到正確版本的內容,處理此議題的方式很簡單,我們只需要在模式的描述內容裡加入可以辨別的模式版本資訊即可。

 第三個議題就是我們在參照模式的時候,如何確認該版本模式的內容還是正確無誤的?在此我們需要產生一個可以信任的機制。有關於版本正確的信任機制,有賴於軟體開發工具中稽核機制的設計。以.NET而言,該語言的軟體開發工具已經支援這樣的需求;而以Java而言,除了一般商業化的軟體開發工具有相關的支援之外,我們也可以尋找是否有類似的開放原始碼的相關專案,來協助我們處理這一個議題。

5.建模或是程式設計?(Modeling or Programming?)

 一般來說,我們會對於建造模式(build model = modeling,建模)與程式設計產生混淆,也不容易瞭解建模的重要性,雖然我們曾經提過模式的特性在於他的詮釋資料很齊全,可以供工具來進行自動化發展之用,所以有人會利用註解(notation)的有無,來判斷他是模式語言還是程式語言。但是事實上卻不是如此,原因如下:

(1) 一般的程式語言都允許在原始碼檔案中間,進行相關的文字註解工作(textual notation),所以就常常會被誤認為程式語言一定是文字的,但是事實上以圖形為主的程式語言的例子也是存在很多的例子,例如:Lego Mindstorms,一個用來建造機器人的圖形程式語言。圖形程式語言定義了圖形元素來表示圖形的程序與操作流程,文字結構的語言並不一定是程式語言,就好像XML是一個大家都知道的文字結構語言,但是它卻不是程式語言。

(2) 模式語言除了文字的內容之外,它還是可以利用圖形化的註解方式來呈現,所以也形成了這樣的誤解:模式語言一定要用圖形表示的方法;也因為利用圖形表示方式的模式語言並沒有辦法有效完整地表達整個軟體應用系統,所以也造成了一般人的誤解,程式語言無法利用圖形表示的方法來呈現。其實模式語言可以利用很多種方式來呈現,就如同我們先前所提過的模式的特性,模式是需要經由不同的表示方式來呈現整個軟體系統的全貌。

 因此,利用軟體規格的形式來判斷是否為模式語言或是程式語言的方式,並不是處在一個合理的推論基礎上。也就是說,我們依據簡單的幾項因素來判斷該語言是屬於模式語言或是程式語言是不合理的,也是不需要的。瞭解模式語言的重要性在於,模式語言與程式語言都是軟體規格的描述,對於軟體開發人員來說,都
是重要的,因此除了基本的程式語言之外,可以協助我們快速發展的模式語言同樣也是重要的因素。

 因為模式語言容易與程式語言混淆,因此Czarnecki將其稱之為GPL(general purpose language,針對一般化的抽象化)與DSL(domain specific language,針對特殊領域的抽象化)【註5】。

  經過以上的說明,希望對讀者而言,可以增加對於樣式與模式這兩個名詞的瞭解,下一期的內容之中我們將進行到如何利用模式語言來進行模式驅動的軟體開發(model-driven development)。(待續)

參考資料與文獻

【註1】:Cleaveland, "Program Generators with XML and Java", Prentice Hall, 2001, ASIN:0130258784。

【註2】:大多數的正規化語言的目的就是將大量使用於低階軟體語言的慣例,這些慣例我們通常稱之為樣式語言或是程式的片語(programming idiom),也就是將這一些慣例編碼成另外一組我們比較懂的語言。

【註3】:本圖來源修改自為『軟體工廠』一書內頁第213頁圖6.8,有興趣的讀者可以參閱原文。

【註4】:Web Service Definition Language (WSDL),定義Web Services的語言,內容記錄於由XML文件中,請參考W3.org的定義,available at URL <http://www.w3.org/TR/wsdl>

     另外,以可以參考在Wikipedia中,對於WSDL的中文解釋,WSDL – Wikipedia,available at URL < http://zh.wikipedia.org/wiki/WSDL>

【註5】:請參閱原書中的內容,K. Czarnecki and U. Eisenecker, "Generative Programming: Methods, Tools, and applications", Addison-Wesley, 2000。




上一篇 | 返回電子報
 
 本電子報所有文字、圖片版權為中央研究院所有 。 電子報出版系統由中央研究院資訊服務處開發。