天天看點

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 聯系。 

繼續閱讀