COM是Component Object Model (組件對(duì)象模型)的縮寫(xiě)。BREW基本上遵從COM這一組件構(gòu)架的。組件架構(gòu)的一個(gè)優(yōu)點(diǎn)就是應(yīng)用可以隨時(shí)間的流逝而發(fā)展進(jìn)化,除此之外,使用組件還有一些可以使對(duì)以有應(yīng)用的升級(jí)更加方便和靈活的優(yōu)點(diǎn),如應(yīng)用的定制,組件庫(kù)以及分布式組件等。

BREW的COM屬性

COM原本是微軟公司為了計(jì)算機(jī)工業(yè)的軟件生產(chǎn)更加符合人類(lèi)的行為方式開(kāi)發(fā)的一種軟件開(kāi)發(fā)技術(shù)。在COM構(gòu)架下,人們可以開(kāi)發(fā)出各種各樣的功能專(zhuān)一的組件,然后將它們按照需要組合起來(lái),構(gòu)成復(fù)雜的應(yīng)用系統(tǒng)。由此帶來(lái)的好處是多方面的:可以將系統(tǒng)中的組件用新的替換掉,以便隨時(shí)進(jìn)行系統(tǒng)的升級(jí)和定制;可以在多個(gè)應(yīng)用系統(tǒng)中重復(fù)利用同一個(gè)組件;可以方便的將應(yīng)用系統(tǒng)擴(kuò)展到網(wǎng)絡(luò)環(huán)境下;COM與語(yǔ)言,平臺(tái)無(wú)關(guān)的特性使所有的程序員均可充分發(fā)揮自己的才智與專(zhuān)長(zhǎng)編寫(xiě)組件模塊等等。

BREW SDK中所提供的服務(wù)實(shí)際上是一些小的二進(jìn)制可執(zhí)行程序形成的組件,它們可以給應(yīng)用程序、操作系統(tǒng)以及其他組件提供服務(wù)。開(kāi)發(fā)自定義的BREW組件(例如,BREW 擴(kuò)展類(lèi))就好像是開(kāi)發(fā)動(dòng)態(tài)的、面向?qū)ο蟮腁PI。多個(gè)BREW對(duì)象可以連接起來(lái)形成應(yīng)用程序或組件系統(tǒng)。并且組件可以在運(yùn)行時(shí)刻,在不被重新鏈接或編譯應(yīng)用程序的情況下被卸下或替換掉。

COM實(shí)際上象結(jié)構(gòu)化編程及面向?qū)ο缶幊谭椒菢?,也是一種編程方法。使用組件的種種優(yōu)點(diǎn)直接來(lái)源于可以將它們動(dòng)態(tài)的插入或卸出應(yīng)用。為了實(shí)現(xiàn)這種功能,所有的組件必須滿足兩個(gè)條件:第一,組件必須動(dòng)態(tài)鏈接;第二,它們必須隱藏(或封裝)其內(nèi)部實(shí)現(xiàn)細(xì)節(jié)。動(dòng)態(tài)鏈接對(duì)于組件而言是一個(gè)至關(guān)重要的要求,而消息隱藏則是動(dòng)態(tài)鏈接的一個(gè)必要條件。

總的來(lái)說(shuō),BREW可以在運(yùn)行時(shí)刻同其他組件連接起來(lái)構(gòu)成某個(gè)應(yīng)用程序,可以動(dòng)態(tài)的插入或卸出應(yīng)用,是動(dòng)態(tài)鏈接的。BREW隱藏(封裝)其內(nèi)部實(shí)現(xiàn)細(xì)節(jié),基于BREW的應(yīng)用以二進(jìn)制的形式發(fā)布,可以在不妨礙已有用戶的情況下被升級(jí)。BREW的自定義擴(kuò)展按照一種標(biāo)準(zhǔn)的方式來(lái)宣布它們的存在。

BREW中的接口

COM的對(duì)象之間通過(guò)接口進(jìn)行交互。接口是包含了一組函數(shù)的數(shù)據(jù)結(jié)構(gòu),通過(guò)這組數(shù)據(jù)結(jié)構(gòu),代碼可以調(diào)用組件對(duì)象的功能。接口定義了一組成員函數(shù),這組成員函數(shù)是組件對(duì)象暴露給用戶的所有可用信息,客戶可以利用這些信息取得組件提供的服務(wù)。與COM使用GUID作為接口的唯一標(biāo)識(shí)類(lèi)似,BREW使用稱(chēng)之為ClassID的一個(gè)4字節(jié)無(wú)符號(hào)整數(shù)作為唯一標(biāo)識(shí)。

BREW提供了一組固定的接口,哪怕以后實(shí)現(xiàn)的方式出現(xiàn)了變化,只要應(yīng)用程序和組件程序之間的接口不變,就不需要任何改變。從技術(shù)上講,接口是包含了一組函數(shù)的數(shù)據(jù)結(jié)構(gòu),通過(guò)這組數(shù)據(jù)結(jié)構(gòu),用戶可以調(diào)用組件的功能。同樣與COM類(lèi)似,BREW使用基于接口對(duì)象的引用計(jì)數(shù)來(lái)控制接口的生存期,并且為多個(gè)程序之間共享統(tǒng)一接口對(duì)象提供了有效的控制手段。一般來(lái)說(shuō),引用計(jì)數(shù)技術(shù)包括三種實(shí)現(xiàn)方式:一是使用全局引用計(jì)數(shù),這樣可以精確的控制整個(gè)應(yīng)用程序模塊的生存期;二是使用針對(duì)每個(gè)接口一個(gè)引用計(jì)數(shù)跟蹤接口的使用情況,但是對(duì)于實(shí)現(xiàn)了多個(gè)接口的對(duì)象,這樣做的效果就是分辨率太細(xì)這將導(dǎo)致無(wú)法精確跟蹤每個(gè)接口的使用情況,造成管理困難,唯一的好處就是能夠減少資源的消耗;三是使用每個(gè)對(duì)象一個(gè)引用計(jì)數(shù)這樣可以精確控制對(duì)象的生存期,并且在復(fù)雜度和資源消耗上能夠達(dá)到較好的平衡。BREW接口的引用計(jì)數(shù)使用方式三,是針對(duì)每個(gè)接口類(lèi)或者是應(yīng)用程序采用引用計(jì)數(shù)。

應(yīng)用程序用一個(gè)指向接口數(shù)據(jù)結(jié)構(gòu)的指針來(lái)調(diào)用接口成員函數(shù),如圖4-5所示。

?????? 圖 4-5: BREW應(yīng)用程序的接口指針示意

實(shí)際上,應(yīng)用所使用的接口指針也指向一個(gè)指針,這個(gè)指針則指向一組函數(shù)的定義(即接口函數(shù)表,又稱(chēng)為虛函數(shù)表,vtable)。每一個(gè)接口成員函數(shù)的第一個(gè)參數(shù)必須為指向這個(gè)定義這個(gè)接口的組件類(lèi)型的指針(可以參考一下用C模擬C++的過(guò)程,在C++的類(lèi)定義中,每一個(gè)成員函數(shù)的第一個(gè)參數(shù)都是隱含的,即編譯系統(tǒng)自動(dòng)添加的this指針),這是因?yàn)榻涌诒旧聿荒塥?dú)立存在,它必須依附于某個(gè)COM組件而存在。因此這個(gè)指針可以提供對(duì)象實(shí)例的屬性信息,在調(diào)用過(guò)程中可以知道是在對(duì)那個(gè)COM對(duì)象進(jìn)行操作。 圖中到圓邊方框之前,定義的都是指針,真正的實(shí)現(xiàn)要依賴(lài)于COM組件給出的實(shí)現(xiàn),對(duì)于客戶來(lái)說(shuō),只需要知道應(yīng)該調(diào)用什么就足夠了,但是對(duì)于組件來(lái)說(shuō)就必須考慮這樣的功能應(yīng)該怎樣實(shí)現(xiàn)。接口是客戶程序和組件程序之間的橋梁,接口應(yīng)該具有不變性,并且一個(gè)COM對(duì)象也應(yīng)該支持多個(gè)接口。

對(duì)于同一個(gè)類(lèi)的所有對(duì)象,它們分別擁有不同的數(shù)據(jù)成員存儲(chǔ)區(qū),但是共享同一份成員函數(shù)的拷貝,在不同的對(duì)象調(diào)用成員函數(shù)的時(shí)候根據(jù)對(duì)象隱式傳遞的this指針判別是哪個(gè)對(duì)象調(diào)用了成員函數(shù)。對(duì)于接口的實(shí)現(xiàn)也類(lèi)似,類(lèi)似于C++中的數(shù)據(jù)成員,對(duì)于指向虛函數(shù)表的指針,每個(gè)接口指針都有屬于自己的一份拷貝,而對(duì)于提供功能實(shí)現(xiàn)的虛函數(shù)表,則共享同一份拷貝(圖4-6)。

?

圖 4-6: BREW中的虛函數(shù)表

?

BREW中的ISHELL_createlnstance方法使用了對(duì)象創(chuàng)建型設(shè)計(jì)模式的抽象工廠模式,它提供了創(chuàng)建一系列相關(guān)或者是相互依賴(lài)對(duì)象的接口,而無(wú)須指定他們具體的類(lèi),這樣可以只提供BREW 的接口,而在需要的時(shí)候根據(jù)具體的ClassID創(chuàng)建具體的實(shí)現(xiàn),一般來(lái)說(shuō)抽象工廠模式有以下的幾個(gè)優(yōu)點(diǎn):

(1)分離了具體的實(shí)現(xiàn)和接口:只需指定不同的接口和classlD,既可成功創(chuàng)建接口對(duì)象,而無(wú)須關(guān)心是何種實(shí)現(xiàn);

(2)有利于更新產(chǎn)品模塊:當(dāng)有新的模塊更新的時(shí)候,無(wú)須更改程序,只需替換相應(yīng)的模塊實(shí)現(xiàn),這樣就可以使用新的模塊;

(3) 有利于產(chǎn)品的一致性;由于classID的唯一性,可以創(chuàng)建指定的對(duì)象實(shí)現(xiàn),而不會(huì)在有眾多實(shí)現(xiàn)的應(yīng)用中出現(xiàn)混亂。

對(duì)于抽象工廠模式難以支持新種類(lèi)產(chǎn)品的缺點(diǎn),在BREW 的設(shè)計(jì)架構(gòu)中給予消除了,由于重新啟動(dòng)BREW環(huán)境的時(shí)候,會(huì)對(duì)系統(tǒng)范圍內(nèi)的ClassID 予以重新注冊(cè),因此當(dāng)新種類(lèi)加入的時(shí)候,只需要提供確定的ClassID 既可成功創(chuàng)建應(yīng)用。

?