使用模型驅動的方法和 UML 2.0 及 Ada 2005 介面來開發更靈活的 Ada 應用程式

myattitude發表於2010-06-26

轉自http://www.ibm.com/developerworks/cn/rational/10/developingsmarteradaapplicationsusingmodeldrivenapproach/

引言

物件管理組(OMG)的統一建模語言 1.x(UML 1.x)的初始版本,源自於三種物件導向的方法(Booch,OMT 和 OOSE),並從建模語言設計、物件導向的程式設計以及結構化描述語言整合了一系列的最佳實踐方式。UML 1.x 語言對於為類建模功能強大,這些關係包括物件導向的關係,例如聯絡、附屬、組合、聚合與泛化。圖 1 顯示了使用類圖來聯絡類的方式。


圖 1. UML 1.0 中的類圖
螢幕截圖顯示了 UML 1.0 類圖

但是當您在構建大型的系統時,我們想要只關注於類在聚合度方面是如何聯絡的,以及是如何隔離的。儘管在 UML 1.x 中可以定義介面,但是,對於結構化的符號沒有內在的建模支援,這些符號顯示了一個系統是怎樣分解為子系統,或者子系統在這樣的集合裡是如何聯絡的。


使用 UML 2.x 對大型系統建模

在開發最新的統一建模語言標準時,作出了最大的改進,UML 2.x ,用於為大型系統的建模提供支援。特別需要指出的是,UML 2.x 努力鞏固系統之系統的概念,其中任意的系統都可以由一系列的子系統組成,而子系統又可進一步分解為它自己擁有的子系統。為了做到這一點,UML 2 引入了一個稱為組合結構的新概念。在這種背景下,所謂的“結構”是相互聯絡元素的組合,這些元素代表了執行時例項協作以達到一些公共的目標(見於資源)。因此,一個結構化的類,就包含了其他的類。

類之中類的例項就是所謂的部件。例如在圖 2 中, Builder1 是一個結構化的類,它由兩個部件組成,一個是 Transmitter 類的例項與一個 Receiver 類的例項。類可以由那些擁有部件的類組成,允許您按照層級結構將一個系統逐步分解成任意的層次。


圖 2. 提供的和需要的介面與行為埠
顯示組合類的圖

在 UML 2.x 中還引入了埠的概念,它代表了識別符號(例如類與角色)例項與其環境之間的交流點,或者識別符號例項與它所包含例項(例如它的部件)之間的交流點。與埠相聯絡的介面指定了埠上可能發生的交流的本質。

範例顯示了 Transmitter 與 Receiver 通過埠來聯絡。Receiver 擁有一個行為埠去處理訪問。在一個行為埠上介面提供的具體操作由擁有埠類的例項來執行。圖 3 顯示了通過埠間聯結器呼叫 Receiver 上非同步資訊的 Transmitter 。對於 Receiver 類來說,它簡單地列印了對操控臺視窗接受的字元。


圖 3. 執行 Builder1 作為程式的螢幕截圖
Tx 與 Rx 字元文字操控臺


使用埠提供的和需要的介面

在 UML 中一個識別符號(例如一個類或者角色)可以擁有任意數量的埠。每一個埠都需要根據其識別符號來得到獨一無二的名字。可以使用棒棒糖和插座符號通過一個埠來獲得提供的操作與需要的操作。

  • “需要的介面”描述了識別符號對其環境通過埠發出的請求。它用插座來標示(有時也稱為一個杯)。
  • “提供的介面”描述了其環境通過埠對識別符號的請求。它用棒棒糖來標示(有時也稱為一個球)。

在面臨需要的介面時,可以通過啟用對其埠的服務,來設計和實施類。因為這樣的埠在概念上解除了對提供者提供的類的耦合。

更為重要的是,可以使用具體的實現了相同介面的實施方案。這就使得埠對於基於構件的設計功能十分強大。因此使用埠可以輕鬆地將構件從一個集合轉移到另一個集合中去。這意味著構件可以在不同的背景下使用,或者在完全不同的系統中使用。

例如,在圖 4 中,Transmitter 完全沒變,但是 Receiver 類卻被 Banner 類提供,該 Banner 類提供了相同的介面,而且是 IReceiver 介面的完全不同的實施方案。


圖 4. 非行為(中轉)埠
顯示組合類的圖

該圖還演示了非行為埠的概念。Banner 類沒有提供 IReceiver 介面的具體實現方案;但是它中轉其埠對內部構件的啟用。非行為埠就是中轉埠或者授權埠,它們向內部構件傳送訪問。

該圖還展示了使用符號來“插入與執行”擁有相同介面的不同構件是多麼的輕鬆。執行 Builder2 的輸出顯示在圖 5 中。它演示了“itsBanner”部分是怎樣將它接受的字元,以 滾動的標題形式基於畫素的字母顯示出來,而不是簡單地將它們列印出來。重要的是,您可以更改類的實施方案,該類提供了 IReceiver 介面,而不用影響使用其服務的 Transmitter 類,圖中還演示了在使用埠時“插入和執行”構件是多麼的容易。


圖 5. 執行 Builder2 作為程式的螢幕截圖
顯示帶有文字的操控臺視窗

一個給定的埠可以協調以提供任意給定數量提供的或者需要的介面,而一個識別符號可能會有任意數量命名的埠。對於前沿性的 UML 工具,例如 IBM Rational® Rhapsody® 方案中存在的問題,在於怎樣將 UML 中的構造合成為一個目標語言執行方案。


在 Ada 中表達一個物件導向的設計

在研究對映到埠之前,您必須先要理解 Ada 與 UML 之間的關係。當您在使用這些語言的單獨環境中開發軟體時,物件導向的設計中類與介面的關鍵概念,對映到 Ada 語言構造,是我們最大的關注點。

類是物件導向設計的構建模組,並定義了一系列物件的描述,這些物件共享了相同的屬性、操作、關係與語義(見於圖 2)。類的概念並不是 Ada 語言原創的。它通常使用 Ada 記錄來合成以定義類的屬性,並使用 Ada 包來定義可以呼叫該型別物件的操作 ,它是通過將一次處理作為操作訪問的首個引數傳遞給記錄來完成的。

介面的概念在 UML 中也很重要。所謂的 UML 介面定義為用於指定類或者構件服務的一系列操作。一個介面通常由不止一個的服務簽名組成。通過在 UML 中說明一個介面,您可以在一個抽象的簽名中來宣告需要的行為,這種抽象的簽名獨立於具體的實施方案之外。介面是組成一個大型系統的一個重要方面,因為您可以使用介面來定義某個子系統“提供的”或者“需要的”操作的公共檢視。

使用 Ada 95 語言,就可以使用 Ada 包與抽象的 null 記錄型別來合成介面了,其中 Ada 包用於分組那些可以操作特定型別物件的子程式。Ada 95 存在的問題在於,它只支援一個獲得的型別擁有即時的起源。因為記錄型別用作物件操作啟用的基礎,所以這意味著某個類(或者組合類)給定埠上“需要的”或者“提供的”介面的數量只限於一,意味著不允許一個埠上存在多個介面。

本文向您展示了 Ada 2005 是怎樣提高 Ada 開發團隊的能力,以儘量使用高階的 UML 2.x 技術,以前使用像 C++ 和 Java 之類執行語言的開發員從這項技術中受益匪淺。Ada 2005 介面與 UML 介面之間協同支援的一個關鍵 UML 2 概念。這項埠支援組合結構的定義,這種結構中清晰但是抽象的介面,定義了“提供的”服務,或者客戶所“需要的”服務。


利用 Ada 2005 介面

在 Ada 2005 中,引入了一個新的保留詞 介面 來解決單次繼承性的限制問題。Ada 2005 中的所有介面型別是絕對標記的型別。它們支援執行時排程(見於 圖 3. 錯誤:沒有發現引用源)。不像抽象的型別一樣,介面不能宣佈構件或者資料;它是用於定義可以啟用子程式的簽名的基礎。因為 Ada 2005 中這樣的介面只允許有抽象的子程式以及 null 程式作為操作。

下面的圖 6 顯示了兩個介面。如果某項操作被宣佈為 抽象的 那麼繼承的類必須提供了一個具體的實施方案。如果某個操作宣佈為帶有 null 關鍵詞,那麼繼承的類就可以選擇忽略 null 程式。


清單 1. 抽象的子程式與 Ada 2005 中的 null 程式

   package ILetter is

   type ILetter_t is interface;

   procedure Refresh (this : in out ILetter_t) is abstract;
   procedure Setup (this : in out ILetter_t; The_Char : in Character) is abstract;

end ILetter;

package IPrint is

   type IPrint_t is interface;

   procedure Print(This: in out IPrint_t, The_String : in String) is null;

end IPrint;

在 Ada 95 中,一個抽象的型別只能擁有一個即時的起源,但是在 Ada 2005 中,可能會從標記型別的多種介面中獲得一個新的型別。您可以引用首個型別作為它的父類,並將其他的作為起源 。


圖 7. 使用介面的多個介面

with ILetter;
with IPrint;

package Banner_Letter is

   type Receiver_t is new ILetter.ILetter_t and IPrint.IPrint_t with private;

   procedure Refresh (this : in out Receiver_t);
   procedure Setup (this : in out Receiver_t; The_Char : in Character);
   procedure Print(This: in out Receiver_t, The_String : in String);

private

   (hidden attributes)

end Banner_Letter;
        

定義介面的能力意味著訪問者抽象於操作的具體實施操作以外。在圖 8 中,類圖顯示了 Screen 擁有一列的零或者更多的 ILetter 物件。在這個例子中,Screen 類通過 ILetter 介面來啟用操作,通過一系列的 ILetters 來進行迭代。對介面的訪問會導致實時分配給 Banner_Letter 類提供的具體實施方案。使用這種抽象模式,Screen 就可以使用 ILetter 的不同實施方案了,假設它實現了 ILetter 介面操作的簽名。


清單 2. 介面的使用與實現
類圖與實現的介面

埠的程式碼工作模式很相似。如果是行為的埠,那麼對提供的操作所做的訪問是由擁有該埠的類處理的。這意味著擁有的類“實現”了埠上提供的介面。當有客戶呼叫了一個行為埠上的抽象操作時,那麼訪問就會分配給該類了。


接線程式碼的自動化合成

在一個非行為的埠上,當客戶呼叫一個抽象操作時,您需要響應對類的請求,該類實現了提供的介面。

關鍵之處在於,該埠接線程式碼是規則的,並且可以基於在組合結構圖上定義的連結來自動生成。這意味著使用者並不需要編寫任何附加性的程式碼,他們可以使用影像化的符號來將某個部件置於給定的背景下,而程式碼生成員則可以基於定義的規則集來合成接線程式碼。例如,使用 Rational Rhapsody 環境,您就可以定義您想要構建一個 Builder2 組合類,而它以自動生成的模式來集合並實現了所有需要的部件,以及傳送部件之間資訊所需要的接線程式碼。

這就極大地簡化了整合過程,並使得開發員可以使用影像化的 UML 2.x 概念來輕鬆“插入和執行”構件,以定義它們聯絡的方式。


總結

本文向您展示了 Ada 2005 是怎樣提高 Ada 開發團隊的能力,以儘量使用高階的 UML 2.x 技術,以前使用像 C++ 和 Java 之類執行語言的開發員從這項技術中受益匪淺。Ada 2005 介面與 UML 介面之間協同支援的一個關鍵 UML 2 概念。這項埠支援組合結構的定義,這種結構中清晰但是抽象的介面,定義了“提供的”服務,或者客戶所“需要的”服務。

定義介面以及分解系統,是達到一個大型系統的重要方面。使用 UML 2.x 您就可以不但將一個大型的系統分解成各個部件,而且還能清晰地分辨出子系統的界限並將其抽象化,這使得地理位置分散的團隊可以同時獨立地處理不同的系統構件。它還支援權衡可再用構件的重複使用,以降低總體的開發時間或者投入。一旦您建立了一個帶有部件與介面的類,那麼接下來您就可以在多種背景下重複使用它了。

有了建模工具的支援,您就可以自動生成構件與所有需要的構建檔案之間的連線程式碼,以集合構件。這種簡化在整合期間將分隔開的工程部件組合到一起。當然,模型還包含了許多沒有同步化的程式碼,這些程式碼提供了一個廣闊的背景;例如用例,對需求的追蹤性,以及其他關鍵的產品工件。這使得開發員受益匪淺,因為您可以關注於設計程式,而不用去管將程式碼整合起來。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14780914/viewspace-666348/,如需轉載,請註明出處,否則將追究法律責任。

相關文章