基于構件復用的軟件方法與COM支持

發表于:2008-02-20來源:作者:點擊數: 標簽:構件復用
構件復用作為一種現實有效的軟件 開發 方法正受到越來越多的重視和研究。近年來,隨著DNA, 中間件 等三層體系結構和分布式對象的興起,為基于可復用構件的軟件體系結構賦予了更大的內涵。從而使我們在評價構件復用的意義時,不應只局限于開發周期的縮短,軟件 質
構件復用作為一種現實有效的軟件開發方法正受到越來越多的重視和研究。近年來,隨著DNA,中間件等三層體系結構和分布式對象的興起,為基于可復用構件的軟件體系結構賦予了更大的內涵。從而使我們在評價構件復用的意義時,不應只局限于開發周期的縮短,軟件質量的可靠提高,更要認識到構件組裝式的開發在系統維護(如版本更新,功能增刪等),分布式計算等方面所帶來的極大便利。由于維護階段占軟件開發周期總成本的67%左右,因此構件重用對整個軟件產業的重要意義就不言而喻了.從維護和分布計算的角度考慮,構件復用就是要實現"即插即用".
  傳統的面向對象編程語言中,基于繼承機制的類的復用,只是源代碼級的重用,在源代碼不可得的情況下(構件產業化的發展趨勢下,這種情況很普遍),就變得毫無意義了.更為重要的是,聯編以后,類構件就只是一個邏輯上的虛幻的概念了,不會給將來可能的處理帶來任何方便.
  MicroSoft自90年代初就進行了COM的開發,歷經OLE1,VBX組件,OLE2,ActiveX,COM+的不斷完善,現已成為一個相當成熟的組件模型,對構件復用提供了有力的底層支持.
一 COM對象的封裝
  COM是一個二進制的標準,它詳細規定了一個COM組件所應具有的內存結構.COM對象間的交互完全基于對此內存結構的操作.因此可以在很大程度上忽略不同編程語言,應用環境之間的差別,解決了重新編譯重新發行的問題.二進制代碼級的兼容性要求操作系統的支持,但是COM描述對象連接的方法與傳統的API式共享系統服務不同.連接建立后,COM底層庫不再被需要,停止耗用系統資源,與API相比,操作系統必須一直管理組件之間的連接.
  COM用接口的概念對組件的功能屬性進行完全的封裝.與組件的通信必須通過接口進行.接口不僅是一個邏輯上的概念,而且也存在著與之相對應的物理內存結構(VTABLE).一個對象可以對應多個接口,一個接口也可以由多個對象所實現,表現出靈活的多態性.同時也為版本管理提供了方便.當使用新版本的組件替換老版本時,只要該組件實現了舊版本的接口(通過包容,聚合等手段),就保證了其與原用軟件系統的兼容.同時新增功能(新的接口)又可被自然的使用.
  接口完全封裝了內部功能,屬性的具體實現,使得COM對象對外表現為"黑盒"結構,完全吻合面向對象系統所要求的"強內聚性".但由于對接口的過多強調,COM組件一般不具備廣泛提倡的"弱耦合性"的特點.不過,微軟一向重視接口的不變性,試圖用接口的標準化推動服務的標準化,以接口為基礎為軟件復用建立實用的框架.其實ActiveX技術規范中的相當大一部分都是通過定義標準的接口及其相互之間的邏輯關系來確定的.
二 自動化
  在考慮調用接口內成員函數的具體實現時,就會發現由于組件的特殊性,這種實現需要與通常完全不同的規范. 需要解決的問題有:源程序中如何標識一個組件(物理上,就是一段已經存在了的,具有一定功能的二進制代碼),對于組件內特定函數的調用,編譯器將如何做出處理,如何進行參數的檢驗及返回值的收集.
  在舊的編程模式中,以上問題的解決均需要一個對組件進行充分定義的說明性文件.而且,該說明性文件的格式必須完全符合所用的編程語言的語法.這就產生了以下一些矛盾.首先,為每一個發行組件均配置各種不同版本的說明文件在實踐中并不可行;第二,即使這樣的頭文件通過類型庫自動轉換得到,為各種編程語言提供這種轉換工具同樣是不可行的;第三,組件中所用到的數據類型并不一定總能與目標編稱語言一一對應;第四,這種笨拙的實現方法,與構件的"即插即用"概念相去甚遠,程序員難以接受.
  針對以上問題,COM規范提出了自動化技術,較好的實現了以符號為導航的動態綁定. Idispatch是實現這一點的關鍵接口.
Class Idispatch : public Iunknown
{
public:
virtual HRESULT GetTypeInfoCount(UINT * pctinfo) = 0;
virtual HRESULT GetTypeInfo(UINT iTinfo,LCID
lcid,ItypeInfo ** ppTInfo) = 0;
virtual HRESULT GetIDsOfNames(REFIID riid,LPOLESTR *
rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId) = 0;
virtual HRESULT Invoke(DISPID dispIdMember,REFIID
riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,
VARIANT *pVarResult,EXCEINFO *pExcepInfo,
UINT *puArgErr) = 0;
};
  在自動化對象中,每一個成員函數均對應一個分發ID(DISPID),服務導航器InVoke就是通過此分發ID建立與目標函數的連接.可以用GetIDsofName實現符號(函數名)到ID的映射.因此,應用程序就有了一個統一的界面來使用組件提供的各項服務.
  對于數據類型的兼容性問題,微軟提供了一個生硬的解決方法.定義一個盡可能"包羅萬象"的大的數據結構VARIANT
typedef struct tagVARIANT
{
VARTYPE vt; //類型標示
union
{ // 傳值類型
short iVal;
long lVal;
byte bVal;
float fltVal;
……
// 引用類型
short *piVal;
……
IUnknown **ppunkVal;
IDispatch **ppdispVal;
VARIANT *pvarVal;
void *byref;
};
};
  自動化對象與其調用者之間參數與返回值的傳遞,必須在VARIANT的范圍之內進行.各種不同種類的VARIANT型參數之間的轉換,可以在InVoke中實現.為程序員提供更加智能化的編程界面(如VB中實現的那樣).
  COM為所有的組件對象規定了一個必須實現的基接口IUnknown,這不僅定義了最基本的公共服務,而且還使一個指向IUnknown接口的指針客觀上成為組件實例的對象標示.除對象生存期的管理外,這種對象標示還使COM組件具有了自解釋的特性:通過對Iunknown接口的成員函數QueryInterface的調用可以查詢到對象實現的所有接口.
  不過上述自動化的各種優點是以其數據類型的限制和性能的部分損失為代價的.雖然編譯器可以通過類型庫進行前綁定(參數類型的檢查,符號到分發ID的轉換),但是最耗時的InVoke卻難以優化.為此COM規定了雙接口機制,為程序員提供了在動態綁定與靜態聯編之間選擇的自由.同時,自動化技術的存在,也為腳本語言(VBScript, JavaScript)提供了活力.
三 包容和聚合
  作為面向對象系統的重要特性,COM支持兩種重用模型:包容(containment)和聚合(aggregation)它們的思路基本一致,只是在實現方法上有所不同.
  考慮包容的情況,假定已經有一個實現了接口IReuseInterface的COM對象A,由于新的需求,我們又要實現一個新的COM對象B,它既要實現接口IReuseInterface,又要實現接口INewInterface,而且IreuseInterface所提供的服務與對象A的接口基本一致,只要再實現新添加的功能就可完成對象B的開發.最直觀的想法就是在對象B的內部"包容"一個對象A的實例.所有對B的接口IreuseInterface成員函數的調用均在其內部簡單地轉發給對象A,對于B的客戶來說,根本無需知道A的存在.
  包容模型在實現時較為靈活,可以再將調用轉發給內部對象的前后,進行一些本地化的處理,從而彌補A和B各自IreuseInterface接口在功能上的微小差異.
  依然考慮上面的例子,如果B的IReuseInterface接口在功能上與A實現的完全一致,不需要做任何改動.現在采用聚合模型來實現B.對象B本身并不是實現接口IreuseInterface,它只實現接口InewInterface.當B客戶請求IreuseInterface 接口時,對象B把對象A的IreuseInterface接口指針傳遞給客戶程序,因此客戶直接與A進行了交互(雖然它并不知道對象A的存在).
  當然,聚合模型在對Iunknown指針的處理上要比包容模型復雜一些.需要進行對象雙方的合作,并不是每對象都能支持聚合的特性.但聚合體現了組件軟件真正意義上的復用,而包容的重用性只是體現在客戶服務器模型相對性的基礎上.實際也就是客戶程序和組件程序的嵌套關系.這是包容和聚合的本質不同.
四 統一數據傳輸和消息傳遞
  在基于軟件復用開發的應用系統中,各分立的組件對象要相互協作來共同完成某一特定任務邏輯.為支持各種可能復雜的協作關系,僅有參數信息的傳遞是遠遠不夠的,必須提供應用間數據交換的標準方案和事件,消息的通知機制.
  在這兩方面,COM均提供了較為成熟的規范.即統一數據傳輸(UDT,Uniform Data Transfer)和MSMQ.
  眾所周知的OLE程序利用剪貼板傳輸連接對象信息,就是UDT的一種典型應用.統一數據傳輸建立在結構化存儲的基礎上,包括兩方面的內容:首先是數據格式的統一,其次是傳輸協議的建立.統一數據傳輸機制使?quot;數據對象"作為信息實體,通過IDataObject接口暴露其內部信息.由于數據對象本身是一個COM對象,因此它不僅可以表達一般的結構化信息,也可以表達一些非結構化信息.
  傳輸協議任務就是將一個組件提供的數據對象即IdataObject接口指針傳遞給另一個組件對象.接收方得到IdataObject接口指針后就可以利用其成員函數獲取所需的數據.傳輸協議的具體實現與數據交換是完全分開的,因此可以在最大限度與原系統保持兼容的情況下,方便的擴充協議.較常見的傳輸協議包括剪貼板,"拖-放"技術等.另外,為適應一些實時性比較強的應用,COM還提供了"數據變化通?quot;機制,以擴充數據對象與客戶程序之間的雙向通信.MicroSoft Message Queue(MSMQ)版本1是Windows NT操作系統的一個新特征.MSMQ提供可在不可靠的網絡上進行可靠的關鍵任務信息通信.與大多數現代應用程序用緊密耦合且同步通信相反,MSMQ基于一個消息排隊模型來提供一個異步,松散耦合,可靠的網絡通信.出于功能復用及標準化的考慮,MSMQ 使用了面向消息的中間件(MOM Message_Oriented Middleware).MOM提供了一個隊列和消息的通信基礎結構.應用程序向隊列寫入消息,消息中間件將消息傳遞給被請求的隊列,另一個應用程序(或同一應用程序的另一個組件)從目標隊列讀取消息并進行處理.消息的內容完全由讀寫隊列的應用程序控制.MSMQ支持大范圍的隊列類型.公共應用程序隊列對MSMQ客戶是可見的,因為它們發布在一個命名服務器上,即MQIS(Message Queue Information Store,消息隊列信息存儲).MSMQ客戶能夠查詢MQIS來確定是否存在某一公共應用程序隊列以及它已哪臺計算機為主機.另一方面,私有的應用程序隊列不在MQIS中發布.因此,想向私有隊列發送消息,就必須詳細知道此隊列的主機.
五 總結
  企業級應用系統領域中的構件復用,由于有了三層體系結構的支持而變得清晰,明確.在Windows DNA框架中應用系統被分為了表現層,業務層和數據層.其中的業務層又可根據需要分為多個子層.表現層和數據層的重用已經相當標準化了,如各種支持GUI開發的類庫,ActiveX控件,OLEDB,ODBC等.構件復用的重點在業務處理層.筆者認為通過對商業世界中各項服務的明確劃分,對東服務接口的定義標準化,可以有效地實現體系結構和組件的復用.
  隨著Windows 2000的發布,浮出水面的COM+作為COM,DCOM,MTS的某種集成,與操作系統的結合更加緊密. COM+提供了對負載平衡,安全性,消息事件模型,MTS服務的更好支持.同時,COM+的部分特性將在下一代編譯器(Visual Studio 7.0)中有所體現,使得組件化程序設計更加自然,友好.隨著COM+的發表,從現在到將來,COM將成為一條基于Windows的面向組件對象的軟件開發之路.

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97