10.2 橋接模式概述橋接模式是一種很實用的結(jié)構(gòu)型設(shè)計模式,,如果軟件系統(tǒng)中某個類存在兩個獨立變化的維度,,通過該模式可以將這兩個維度分離出來,使兩者可以獨立擴展,,讓系統(tǒng)更加符合“單一職責原則”,。與多層繼承方案不同,它將兩個獨立變化的維度設(shè)計為兩個獨立的繼承等級結(jié)構(gòu),,并且在抽象層建立一個抽象關(guān)聯(lián),,該關(guān)聯(lián)關(guān)系類似一條連接兩個獨立繼承結(jié)構(gòu)的橋,故名橋接模式,。 橋接模式用一種巧妙的方式處理多層繼承存在的問題,,用抽象關(guān)聯(lián)取代了傳統(tǒng)的多層繼承,將類之間的靜態(tài)繼承關(guān)系轉(zhuǎn)換為動態(tài)的對象組合關(guān)系,,使得系統(tǒng)更加靈活,,并易于擴展,,同時有效控制了系統(tǒng)中類的個數(shù)。橋接定義如下:
橋接模式的結(jié)構(gòu)與其名稱一樣,,存在一條連接兩個繼承等級結(jié)構(gòu)的橋,橋接模式結(jié)構(gòu)如圖10-3所示: 在橋接模式結(jié)構(gòu)圖中包含如下幾個角色: ●Abstraction(抽象類):用于定義抽象類的接口,,它一般是抽象類而不是接口,,其中定義了一個Implementor(實現(xiàn)類接口)類型的對象并可以維護該對象,它與Implementor之間具有關(guān)聯(lián)關(guān)系,,它既可以包含抽象業(yè)務(wù)方法,,也可以包含具體業(yè)務(wù)方法。 ●RefinedAbstraction(擴充抽象類):擴充由Abstraction定義的接口,,通常情況下它不再是抽象類而是具體類,,它實現(xiàn)了在Abstraction中聲明的抽象業(yè)務(wù)方法,在RefinedAbstraction中可以調(diào)用在Implementor中定義的業(yè)務(wù)方法,。 ●Implementor(實現(xiàn)類接口):定義實現(xiàn)類的接口,,這個接口不一定要與Abstraction的接口完全一致,事實上這兩個接口可以完全不同,,一般而言,,Implementor接口僅提供基本操作,而Abstraction定義的接口可能會做更多更復雜的操作,。Implementor接口對這些基本操作進行了聲明,,而具體實現(xiàn)交給其子類。通過關(guān)聯(lián)關(guān)系,,在Abstraction中不僅擁有自己的方法,,還可以調(diào)用到Implementor中定義的方法,使用關(guān)聯(lián)關(guān)系來替代繼承關(guān)系,。 ●ConcreteImplementor(具體實現(xiàn)類):具體實現(xiàn)Implementor接口,,在不同的ConcreteImplementor中提供基本操作的不同實現(xiàn),在程序運行時,,ConcreteImplementor對象將替換其父類對象,,提供給抽象類具體的業(yè)務(wù)操作方法。 橋接模式是一個非常有用的模式,,在橋接模式中體現(xiàn)了很多面向?qū)ο笤O(shè)計原則的思想,,包括“單一職責原則”、“開閉原則”,、“合成復用原則”,、“里氏代換原則”,、“依賴倒轉(zhuǎn)原則”等。熟悉橋接模式有助于我們深入理解這些設(shè)計原則,,也有助于我們形成正確的設(shè)計思想和培養(yǎng)良好的設(shè)計風格,。 在使用橋接模式時,我們首先應該識別出一個類所具有的兩個獨立變化的維度,,將它們設(shè)計為兩個獨立的繼承等級結(jié)構(gòu),,為兩個維度都提供抽象層,并建立抽象耦合,。通常情況下,,我們將具有兩個獨立變化維度的類的一些普通業(yè)務(wù)方法和與之關(guān)系最密切的維度設(shè)計為“抽象類”層次結(jié)構(gòu)(抽象部分),而將另一個維度設(shè)計為“實現(xiàn)類”層次結(jié)構(gòu)(實現(xiàn)部分),。例如:對于毛筆而言,由于型號是其固有的維度,,因此可以設(shè)計一個抽象的毛筆類,,在該類中聲明并部分實現(xiàn)毛筆的業(yè)務(wù)方法,而將各種型號的毛筆作為其子類,;顏色是毛筆的另一個維度,,由于它與毛筆之間存在一種“設(shè)置”的關(guān)系,因此我們可以提供一個抽象的顏色接口,,而將具體的顏色作為實現(xiàn)該接口的子類,。在此,型號可認為是毛筆的抽象部分,,而顏色是毛筆的實現(xiàn)部分,,結(jié)構(gòu)示意圖如圖10-4所示: 在圖10-4中,如果需要增加一種新型號的毛筆,,只需擴展左側(cè)的“抽象部分”,,增加一個新的擴充抽象類;如果需要增加一種新的顏色,,只需擴展右側(cè)的“實現(xiàn)部分”,,增加一個新的具體實現(xiàn)類。擴展非常方便,,無須修改已有代碼,,且不會導致類的數(shù)目增長過快。 在具體編碼實現(xiàn)時,,由于在橋接模式中存在兩個獨立變化的維度,,為了使兩者之間耦合度降低,首先需要針對兩個不同的維度提取抽象類和實現(xiàn)類接口,,并建立一個抽象關(guān)聯(lián)關(guān)系,。對于“實現(xiàn)部分”維度,,典型的實現(xiàn)類接口代碼如下所示: 在實現(xiàn)Implementor接口的子類中實現(xiàn)了在該接口中聲明的方法,用于定義與該維度相對應的一些具體方法,。 對于另一“抽象部分”維度而言,,其典型的抽象類代碼如下所示: 在抽象類Abstraction中定義了一個實現(xiàn)類接口類型的成員對象impl,再通過注入的方式給該對象賦值,,一般將該對象的可見性定義為protected,,以便在其子類中訪問Implementor的方法,其子類一般稱為擴充抽象類或細化抽象類(RefinedAbstraction),,典型的RefinedAbstraction類代碼如下所示: 對于客戶端而言,,可以針對兩個維度的抽象層編程,在程序運行時再動態(tài)確定兩個維度的子類,,動態(tài)組合對象,,將兩個獨立變化的維度完全解耦,以便能夠靈活地擴充任一維度而對另一維度不造成任何影響,。
|
|