CORBA 連接:CORBA 3.0 的 IDL


CORBA 連接:CORBA 3.0 的 IDL


內容: 
 
爲什麼使用軟件組件? 
組合接口 
“是”對“具有” 
導航和等價接口 
結束語 
參考資料 
關於作者 
對本文的評價 
 
相關內容: 
 
CORBA Component Model (CCM) 
The OMG's new CORBA Component Model 
CORBA notification services 
 
擴展接口間的關係 
Dave Bartlett ([email protected])
顧問、作家兼講師
2001 年 7 月

“對象管理組織(OMG)”的“接口定義語言”已經能使開發人員根據繼承創建對象關係。然而,當處理複雜設計時,經常需要支持包含多個接口的對 象,並且這些對象是通過組合而不是通過繼承來構造的。本週,Dave Bartlett 通過擴展“組件實現定義語言”與標準化定義組件接口的方式,解釋 了“CORBA 組件模型”如何實現這種需要。
在開始討論軟件組件之前,有必要定義它們是什麼以及爲什麼我們希望使用它們。然後,討論“組件實現定義語言(CIDL)”以及 CIDL 如何使組件式軟件成爲現實。

爲什麼使用軟件組件?
爲什麼我們要使用軟件組件?我們的汽車是由零部件(組件)組成;爲什麼我們喜歡這樣,爲什麼零部件(組件)是重要的?汽車使用零部件(組件)是因 爲當零部件(組件)用壞或發現有缺陷時,很容易替換掉它(比如輪胎)。這有助於管理變更,我認爲這是使用組件的首要原因。在我的汽車裏,我不能保持全部應 用最新的技術,每一個組件隔離了該項技術的某個方面。這導致了使用組件的第二個原因,管理複雜性。分而治之的策略簡化了系統中大量的功能。最後一個原因是 重用。爲什麼重用是最後一個?因爲我從來沒有真正嘗試拆掉我妻子汽車的交流發電機而將它用到我的汽車上,但我猜想我可能會這樣做。這可能需要某種層次的式 樣更新。重用是一個宏偉的目標,但要達到這個目標卻格外困難。如果系統易於維護並且隨着環境變化和技術改進易於升級系統,那麼從長遠來看,該系統的價值將 會極大地增加。腦子裏有了這些目標之後,讓我們創建一些定義。

組件是象這樣的結構化軟件單元,它們:

協同定位函數和數據之間的相關性,所以創建結合 
封裝軟件單元以減少耦合,並將組件用戶與數據存儲細節或功能實現隔離開 
提供唯一的標識,不考慮狀態 

基於組件的軟件的目標是創建高度結合的、合作良好的部件,但各自有明顯不同的任務,以及創建系統中組件間低耦合性。這需要系統設計者從對象規範來 擴展面向對象原則到用接口定義明確地表示對象相關性。這種組件能力的規範可以劃分成跨幾個接口。將組件規範劃分成多個接口可以使組件內相關性被限制到個別 接口,而不是整個組件規範。

例如,提供時間與日期函數的簡單組件也必須實現幾個接口,這些接口使得該組件在組件容器中能合作工作。對組件容器的更改需要對那些接口進行更改,但不需要更改時間與日期函數。反之亦然:可以不改變接口而更新時間與日期函數,這提供了組件的維護功能。

總之,基於組件的系統是不同的,因爲它將規範和實現分離開,還因爲將組件規範分成了表示組件和容器角色的一些具體接口。

組合接口
建立接口之間的關係和建立實現類之間的關係是組件設計的基本行爲。設計這些關係的兩種方式是繼承和組合。“Gang of Four”這本設計模 式書(請參閱參考資料)的第一章通過對對象、實現和重用的廣泛描述展示了對象編程的精髓。這一章明確地提出了使重用成爲現實的困難性。繼承是面嚮對象語言 典型的特徵之一。它也是大多數學生能快速和有效掌握的事物。然而,繼承確實有它的不利之處,而對於這些,學生直到具有更多面向對象的經驗或除非受益於具有 理性意識的導師時,才能意識到。

在 OO 開發中,繼承出現在兩個不同的階段。一方面,接口繼承(也稱作爲子類型),它描述當一個對象用來替換另一個對象時。在 C++ 中,通 過從純抽象類(具有純虛擬成員函數的類)公共地繼承來做到這一點。由於 Java 編程語言有 interface 關鍵字,很容易發現接口繼承。另一方 面,類繼承,它依照另一個對象的實現定義對象實現。類繼承也稱爲實現繼承。所以,雖然一些編程語言不支持接口繼承和實現繼承之間的差別,但優秀的程序員在 實踐中可以區分這兩者。例如,C++ 通過由抽象類定義類型來處理這兩者的差別。

許多設計模式取決於接口繼承和實現繼承之間這種微妙的差別。Observer 設計模式經常用抽象類(它們是純接口)來實現。Composite 模式是用來定義公共實現,而這個組合中的組件定義公共接口。

OMG IDL 總是允許您創建基於繼承的對象關係。然而,很多時候,我們的設計需要支持包含多個接口的對象,而這些接口是通過組合而不是通過繼 承來構造的。對象繼承允許您依照另一個類來定義這個類的實現,而對象組合允許您通過將對象集合或組合在一起來定義一個類。OMG IDL 需要表達組合和 繼承的能力。

OMG 已經認識到這些缺陷,並且一直在嘗試解決它們。在 1996 年,OMG 發佈了 RFP (Request for Proposal)。RFP 的需求將解決對多個接口的需要。CORBA Component Model 被認爲是完成最初 在這個建議下提出的需求。

“是”對“具有”
當通過繼承將子類和超類聯繫起來時,我們可以說子類具有了超類的一些特徵。例如,狗子類“是”犬科超類的代表,可以強制轉化成犬科類。“具有”關係是有很大區別的,它表示組合。

一個重要目標是使用標準接口,針對基於開放標準的組件,也許已經定義了這些接口。播放盒式磁帶和 CD 的 stereo 組件都有相似的接口, 所以我們可以將它抽出來形成它自己的接口。這意味着有一個 CassetteDeck 和 CDPlayer 都使用的 AudioPlayer 接口。 AudioPlayer 類似於清單 1 中所示。

清單 1. AudioPlayer 接口

typedef sequence<octet> SoundBytes;
typedef int Speed;

interface AudioStreamIterator {
    void getStream(out SoundBytes nextSound,
                   out boolean hasMore);
};

interface AudioPlayer {
   attribute string name;
   AudioStreamIterator getSoundStream(in String strSound);
   int play(in AudioStreamIterator as);
   int fastForward(in Speed spd);
   int rewind(in Speed spd);
};

component CassettePlayer supports AudioPlayer{
   //  The facet for Client components.
   provides AudioPlayer audioPort;
};

component CDPlayer supports AudioPlayer{
   //  The facet for Client components.
   provides AudioPlayer audioPort;
};

component Stereo {
   attribute string name;
   // The receptacles for Cassettes or CDPlayers
   uses AudioPlayer Cassette;
   uses AudioPlayer CD;
};

AudioPlayer 接口有四種處理模糊定義類型的基本方法。SoundByte 是八位元的序列。這意味着它是一個不知道長度的字節流,並 且由於它是一個八位元,將不會排列它。getSoundStream() 將返回 AudioStreamIterator 對象,該對象將  SoundByte 裝入其中。由於聲音文件可以是很龐大的,我們可以將這個序列分割成多個部分,從而使 RMI(遠程方法調用)免於陷於困境。 play() 方法將 AudioStreamIterator 作爲“in”參數。fastForward() 允許您快速前進至流的某個地方, rewind() 使您倒回至流前面的某個地方。

這就是我們的接口。component 關鍵字是 CIDL 的添加物之一。component 允許 IDL 設計者在其主體內包含該組件的任 何屬性聲明,以及連同一起的組件平面(組件暴露給外界的接口)和容器(組件使用的接口)的聲明與該組件可能需要的任何事件的源和接收器。然而,請注意,方 法中不允許包含 component 關鍵字。這是因爲我們不是在創建接口 - 我們是在組合接口來形成“組件”。CDPlayer 和  CassettePlayer 組件提供了 AudioPlayer 接口,但 Stereo 組件是作爲客戶機工作,因爲它使用該組件的  CDPlayer 和 CassettePlayer。由於有了這個 CCM 的添加物和新的 IDL 關鍵字,您在創建關係時比以前有更大的靈活性。

AudioPlayer

導航和等價接口
所有平面、容器、事件源、事件接收器和屬性的聲明都映射到生成等價接口(CIDL 規範用這個術語來稱謂)的操作。我必須承認我感到自己正走在刀 刃上,因爲我沒有可以使我能檢測規範和 IDL 的 CCM 和 CIDL 的實現。我的理解是 CORBA 3.0 CIDL 編譯器會爲您從組件定義 自動生成等價接口。所以,CDPlayer 組件有類似於清單 2 所示的等價接口。

清單 2. CDPlayer 接口

interface CDPlayer : Components::CCMObject, ManagedObject{
   AudioPlayer provide_audioPort;
};

等價接口中的操作允許組件的客戶機檢索其平面的引用。除此之外,所有組件從組件基本接口 CCMObject 那繼承,該基本接口提供了帶一般導航操作(通過 Components::Navigation 接口)的等價接口。這個導航提供類似於清單 3 所示的功能。

清單 3. Components::Navigation 功能

module Components {
   valuetype FacetDescription {
     public CORBA::RepositoryId InterfaceID;
     public FeatureName Name;
   };

   valuetype Facet:FacetDescription {
     public Object ref;
   };

   typedef sequence<Facet> Facets;
   typedef sequence<FacetDescription> FacetDescriptions;

   exception InvalidName{};

   interface Navigation {

     Object provide_facet(in FeatureName name)
                         raises (InvalidName);

     FacetDescriptions describe_facets();

     Facets provide_all_facets();

     Facets provide_named_facets (in NameList names)
                                  raises (InvalidName);

     boolean same_component(in Object ref);
   };
};
生成等價接口是用來提供組件接口導航。所有組件接口都會繼承它。如果您熟悉 COM 世界,這會使您想起來自 IUnknown 的  QueryInterface() 和在 CoCreateInstanceEx() 中使用的 Multi_QI 結構。通過該導航提供類似以下的行 爲:

provide_facet() 方法返回由 name 參數表示的平面的引用,或者如果沒有發現由那個 name 參數表示的平面,則返回 InvalidName 異常。 
describe_facets() 操作返回由組件提供的所有平面的序列。返回的值類型 FacetDescription 將包含 RepositoryId 和該平面的名稱。 
provide_all_facets() 類似於 describe_facets,但返回的值類型現在將包含支持每個平面的對象的引用。 
provide_named_facets() 將取一列名稱,並返回包含 names 參數中平面的描述和引用的序列(在結構上與 provide_all_facets() 中返回的結構是一致的)。 
same_component() 將允許客戶機決定是否兩個引用屬於同一個組件實例。該方法是組件實現相關。 

結束語
下個月,我將繼續研究 CCM 中的 CIDL 構造。對於基於 CORBA 的系統,IDL 是基本的構建技術,將這一點牢記在心中是很重要 的。對 IDL 的更改引起了規範和 CORBA 社團的共鳴。添加來創建 CIDL 的關鍵字是相當廣泛和直接明瞭。很明顯,OMG 的夢想是使  CIDL 足夠直接明瞭,以詳述軟件組件之間的各種關係,以及自動生成許多重現函數和服務用法模式。通過擴展 CIDL,OMG 維護了其語言和平臺的 中立,但推動了結合堅實工程原則的軟件標準。

參考資料 

關於下一代 CORBA 的介紹,請參閱 CORBA Component Model (CCM)(developerWorks,2001 年 4 月)上最近的 CORBA 連接。 
在 OMG 主頁上,會發現許多關於 CORBA 更改方面的文檔和討論。 
如果對 CORBA 3.0 的起源感興趣,那麼 CORBA Component Model RFP 是一份很好資料。 
如果想了解 CORBA 和 CCM 有什麼新事物,那麼請關注 CORBA 和 CORBA Component Model (CCM) 頁面。 
Gopalan Suresh Raj 在其個人主頁上提供了一篇有關 CCM 不錯的簡介。 
來自 java.sun.com 的新聞發佈介紹了作爲工業標準的 CCM。 
Dr. Dobb's 全面觀察了 CCM,並研究了 CCM 如何將與 EJB 和 COM+ 相對抗(DR. Dobbs Journal,2001 年)。 
學習更多有關用 CORBA 來編程的基礎知識,請閱讀 Michi Henning 和 Steve Vinoski 的 Advanced CORBA Programming with C++ (Addison-Wesley,2000 年)這本極好的書。 
也可以閱讀 Jon Siegel 的 CORBA 3 Fundamentals and Programming (John Wiley and Sons,2000 年)。 
Java 開發人員應該看一下由 Gerald Brose、Andreas Vogel 和 Keith Duddy 著作的 Java Programming with CORBA(John Wiley and Sons,2001 年)。 
查找關於 RMI 和 CORBA 簡介的 Java 開發人員也許想閱讀 IBM Learning Services 教程 RMI, CORBA, and Distributed Objects。 
從 Object Oriented Concepts Inc 下載 Orbacus 4.1.0 以及附帶的 Notification Service 實現。 
如果想學習 Java 編程,那麼請從 Bruce Eckel 的 Mindview.net 以及他的免費電子版書籍 Java 編程思想,第二版(Prentice Hall,2000 年)開始。 
Gang of Four 一書, Design Patterns: Elements of Reusable Object-Oriented Software 完整地介紹了設計模式(Addison-Wesley,1995 年)。 
WebSphere 開發人員希望瞭解關於  Integrating CORBA ORB with IBM WebSphere Application Server (WebSphere Developer Technical Journal,2001 年 6 月)。 
關於組件,有新的東西?WebSphere 組已經編輯了關於基於組件開發(CBD)的理論和實踐的資源列表。 

關於作者
 Dave Bartlett 居住在美國賓夕法尼亞州的 Berwyn,他是顧問、作家兼講師。他是 Hands- On CORBA with Java 的作者,這是一本適用於公共課程或企業內部培訓的 5 日教程。目前,Dave 正將課程資料編成書,書名是  Thinking in CORBA with Java。Dave 擁有賓州大學的工程和商業碩士學位。如果您對某個主題還有疑問或感興趣,可通過  [email protected] 與 Dave 聯繫。 
  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章