COM是Component Object Model (組件對象模型)的縮寫。BREW基本上遵從COM這一組件構(gòu)架的。組件架構(gòu)的一個優(yōu)點就是應(yīng)用可以隨時間的流逝而發(fā)展進化,除此之外,使用組件還有一些可以使對以有應(yīng)用的升級更加方便和靈活的優(yōu)點,如應(yīng)用的定制,組件庫以及分布式組件等。
BREW的COM屬性
COM原本是微軟公司為了計算機工業(yè)的軟件生產(chǎn)更加符合人類的行為方式開發(fā)的一種軟件開發(fā)技術(shù)。在COM構(gòu)架下,人們可以開發(fā)出各種各樣的功能專一的組件,然后將它們按照需要組合起來,構(gòu)成復(fù)雜的應(yīng)用系統(tǒng)。由此帶來的好處是多方面的:可以將系統(tǒng)中的組件用新的替換掉,以便隨時進行系統(tǒng)的升級和定制;可以在多個應(yīng)用系統(tǒng)中重復(fù)利用同一個組件;可以方便的將應(yīng)用系統(tǒng)擴展到網(wǎng)絡(luò)環(huán)境下;COM與語言,平臺無關(guān)的特性使所有的程序員均可充分發(fā)揮自己的才智與專長編寫組件模塊等等。
BREW SDK中所提供的服務(wù)實際上是一些小的二進制可執(zhí)行程序形成的組件,它們可以給應(yīng)用程序、操作系統(tǒng)以及其他組件提供服務(wù)。開發(fā)自定義的BREW組件(例如,BREW 擴展類)就好像是開發(fā)動態(tài)的、面向?qū)ο蟮腁PI。多個BREW對象可以連接起來形成應(yīng)用程序或組件系統(tǒng)。并且組件可以在運行時刻,在不被重新鏈接或編譯應(yīng)用程序的情況下被卸下或替換掉。
COM實際上象結(jié)構(gòu)化編程及面向?qū)ο缶幊谭椒菢?,也是一種編程方法。使用組件的種種優(yōu)點直接來源于可以將它們動態(tài)的插入或卸出應(yīng)用。為了實現(xiàn)這種功能,所有的組件必須滿足兩個條件:第一,組件必須動態(tài)鏈接;第二,它們必須隱藏(或封裝)其內(nèi)部實現(xiàn)細節(jié)。動態(tài)鏈接對于組件而言是一個至關(guān)重要的要求,而消息隱藏則是動態(tài)鏈接的一個必要條件。
總的來說,BREW可以在運行時刻同其他組件連接起來構(gòu)成某個應(yīng)用程序,可以動態(tài)的插入或卸出應(yīng)用,是動態(tài)鏈接的。BREW隱藏(封裝)其內(nèi)部實現(xiàn)細節(jié),基于BREW的應(yīng)用以二進制的形式發(fā)布,可以在不妨礙已有用戶的情況下被升級。BREW的自定義擴展按照一種標準的方式來宣布它們的存在。
BREW中的接口
COM的對象之間通過接口進行交互。接口是包含了一組函數(shù)的數(shù)據(jù)結(jié)構(gòu),通過這組數(shù)據(jù)結(jié)構(gòu),代碼可以調(diào)用組件對象的功能。接口定義了一組成員函數(shù),這組成員函數(shù)是組件對象暴露給用戶的所有可用信息,客戶可以利用這些信息取得組件提供的服務(wù)。與COM使用GUID作為接口的唯一標識類似,BREW使用稱之為ClassID的一個4字節(jié)無符號整數(shù)作為唯一標識。
BREW提供了一組固定的接口,哪怕以后實現(xiàn)的方式出現(xiàn)了變化,只要應(yīng)用程序和組件程序之間的接口不變,就不需要任何改變。從技術(shù)上講,接口是包含了一組函數(shù)的數(shù)據(jù)結(jié)構(gòu),通過這組數(shù)據(jù)結(jié)構(gòu),用戶可以調(diào)用組件的功能。同樣與COM類似,BREW使用基于接口對象的引用計數(shù)來控制接口的生存期,并且為多個程序之間共享統(tǒng)一接口對象提供了有效的控制手段。一般來說,引用計數(shù)技術(shù)包括三種實現(xiàn)方式:一是使用全局引用計數(shù),這樣可以精確的控制整個應(yīng)用程序模塊的生存期;二是使用針對每個接口一個引用計數(shù)跟蹤接口的使用情況,但是對于實現(xiàn)了多個接口的對象,這樣做的效果就是分辨率太細這將導(dǎo)致無法精確跟蹤每個接口的使用情況,造成管理困難,唯一的好處就是能夠減少資源的消耗;三是使用每個對象一個引用計數(shù)這樣可以精確控制對象的生存期,并且在復(fù)雜度和資源消耗上能夠達到較好的平衡。BREW接口的引用計數(shù)使用方式三,是針對每個接口類或者是應(yīng)用程序采用引用計數(shù)。
應(yīng)用程序用一個指向接口數(shù)據(jù)結(jié)構(gòu)的指針來調(diào)用接口成員函數(shù),如圖4-5所示。
?????? 圖 4-5: BREW應(yīng)用程序的接口指針示意
實際上,應(yīng)用所使用的接口指針也指向一個指針,這個指針則指向一組函數(shù)的定義(即接口函數(shù)表,又稱為虛函數(shù)表,vtable)。每一個接口成員函數(shù)的第一個參數(shù)必須為指向這個定義這個接口的組件類型的指針(可以參考一下用C模擬C++的過程,在C++的類定義中,每一個成員函數(shù)的第一個參數(shù)都是隱含的,即編譯系統(tǒng)自動添加的this指針),這是因為接口本身不能獨立存在,它必須依附于某個COM組件而存在。因此這個指針可以提供對象實例的屬性信息,在調(diào)用過程中可以知道是在對那個COM對象進行操作。 圖中到圓邊方框之前,定義的都是指針,真正的實現(xiàn)要依賴于COM組件給出的實現(xiàn),對于客戶來說,只需要知道應(yīng)該調(diào)用什么就足夠了,但是對于組件來說就必須考慮這樣的功能應(yīng)該怎樣實現(xiàn)。接口是客戶程序和組件程序之間的橋梁,接口應(yīng)該具有不變性,并且一個COM對象也應(yīng)該支持多個接口。
對于同一個類的所有對象,它們分別擁有不同的數(shù)據(jù)成員存儲區(qū),但是共享同一份成員函數(shù)的拷貝,在不同的對象調(diào)用成員函數(shù)的時候根據(jù)對象隱式傳遞的this指針判別是哪個對象調(diào)用了成員函數(shù)。對于接口的實現(xiàn)也類似,類似于C++中的數(shù)據(jù)成員,對于指向虛函數(shù)表的指針,每個接口指針都有屬于自己的一份拷貝,而對于提供功能實現(xiàn)的虛函數(shù)表,則共享同一份拷貝(圖4-6)。
?
圖 4-6: BREW中的虛函數(shù)表
?
BREW中的ISHELL_createlnstance方法使用了對象創(chuàng)建型設(shè)計模式的抽象工廠模式,它提供了創(chuàng)建一系列相關(guān)或者是相互依賴對象的接口,而無須指定他們具體的類,這樣可以只提供BREW 的接口,而在需要的時候根據(jù)具體的ClassID創(chuàng)建具體的實現(xiàn),一般來說抽象工廠模式有以下的幾個優(yōu)點:
(1)分離了具體的實現(xiàn)和接口:只需指定不同的接口和classlD,既可成功創(chuàng)建接口對象,而無須關(guān)心是何種實現(xiàn);
(2)有利于更新產(chǎn)品模塊:當(dāng)有新的模塊更新的時候,無須更改程序,只需替換相應(yīng)的模塊實現(xiàn),這樣就可以使用新的模塊;
(3) 有利于產(chǎn)品的一致性;由于classID的唯一性,可以創(chuàng)建指定的對象實現(xiàn),而不會在有眾多實現(xiàn)的應(yīng)用中出現(xiàn)混亂。
對于抽象工廠模式難以支持新種類產(chǎn)品的缺點,在BREW 的設(shè)計架構(gòu)中給予消除了,由于重新啟動BREW環(huán)境的時候,會對系統(tǒng)范圍內(nèi)的ClassID 予以重新注冊,因此當(dāng)新種類加入的時候,只需要提供確定的ClassID 既可成功創(chuàng)建應(yīng)用。
?