在正式介紹橋接模式之前,我先跟大家談?wù)剝煞N常見文具的區(qū)別,它們是毛筆和蠟筆。假如我們需要大中小 3 種型號(hào)的畫筆,能夠繪制 12 種不同的顏色,如果使用蠟筆,需要準(zhǔn)備 3×12 = 36 支,但如果使用毛筆的話,只需要提供 3 種型號(hào)的毛筆,外加 12 個(gè)顏料盒即可,涉及到的對(duì)象個(gè)數(shù)僅為 3 + 12 = 15,遠(yuǎn)小于36,卻能實(shí)現(xiàn)與 36 支蠟筆同樣的功能。如果增加一種新型號(hào)的畫筆,并且也需要具有 12 種顏色,對(duì)應(yīng)的蠟筆需增加 12 支,而毛筆只需增加一支。為什么會(huì)這樣呢?通過(guò)分析我們可以得知:在蠟筆中,顏色和型號(hào)兩個(gè)不同的變化維度(即兩個(gè)不同的變化原因)融合在一起,無(wú)論是對(duì)顏色進(jìn)行擴(kuò)展還是對(duì)型號(hào)進(jìn)行擴(kuò)展都勢(shì)必會(huì)影響另一個(gè)維度;但在毛筆中,顏色和型號(hào)實(shí)現(xiàn)了分離,增加新的顏色或者型號(hào)對(duì)另一方都沒有任何影響。如果使用軟件工程中的術(shù)語(yǔ),我們可以認(rèn)為在蠟筆中顏色和型號(hào)之間存在較強(qiáng)的耦合性,而毛筆很好地將二者解耦,使用起來(lái)非常靈活,擴(kuò)展也更為方便。在軟件開發(fā)中,我們也提供了一種設(shè)計(jì)模式來(lái)處理與畫筆類似的具有多變化維度的情況,即本章將要介紹的橋接模式。
Sunny 軟件公司欲開發(fā)一個(gè)跨平臺(tái)圖像瀏覽系統(tǒng),要求該系統(tǒng)能夠顯示 BMP、JPG、GIF、PNG 等多種格式的文件,并且能夠在 Windows、Linux、Unix 等多個(gè)操作系統(tǒng)上運(yùn)行。系統(tǒng)首先將各種格式的文件解析為像素矩陣(Matrix),然后將像素矩陣顯示在屏幕上,在不同的操作系統(tǒng)中可以調(diào)用不同的繪制函數(shù)來(lái)繪制像素矩陣。系統(tǒng)需具有較好的擴(kuò)展性以支持新的文件格式和操作系統(tǒng)。
Sunny 軟件公司的開發(fā)人員針對(duì)上述要求,提出了一個(gè)初始設(shè)計(jì)方案,其基本結(jié)構(gòu)如圖所示:
http://wiki.jikexueyuan.com/project/design-pattern-structurized/images/1334505400_2839.gif" alt="" />
在圖的初始設(shè)計(jì)方案中,使用了一種多層繼承結(jié)構(gòu),Image 是抽象父類,而每一種類型的圖像類,如 BMPImage、JPGImage 等作為其直接子類,不同的圖像文件格式具有不同的解析方法,可以得到不同的像素矩陣;由于每一種圖像又需要在不同的操作系統(tǒng)中顯示,不同的操作系統(tǒng)在屏幕上顯示像素矩陣有所差異,因此需要為不同的圖像類再提供一組在不同操作系統(tǒng)顯示的子類,如為 BMPImage 提供三個(gè)子類 BMPWindowsImp、BMPLinuxImp 和 BMPUnixImp,分別用于在 Windows、Linux 和 Unix 三個(gè)不同的操作系統(tǒng)下顯示圖像。
我們現(xiàn)在對(duì)該設(shè)計(jì)方案進(jìn)行分析,發(fā)現(xiàn)存在如下兩個(gè)主要問題:
(1)由于采用了多層繼承結(jié)構(gòu),導(dǎo)致系統(tǒng)中類的個(gè)數(shù)急劇增加,圖中,在各種圖像的操作系統(tǒng)實(shí)現(xiàn)層提供了12個(gè)具體類,加上各級(jí)抽象層的類,系統(tǒng)中類的總個(gè)數(shù)達(dá)到了 17 個(gè),在該設(shè)計(jì)方案中,具體層的類的個(gè)數(shù) = 所支持的圖像文件格式數(shù)×所支持的操作系統(tǒng)數(shù)。
(2)系統(tǒng)擴(kuò)展麻煩,由于每一個(gè)具體類既包含圖像文件格式信息,又包含操作系統(tǒng)信息,因此無(wú)論是增加新的圖像文件格式還是增加新的操作系統(tǒng),都需要增加大量的具體類,例如在圖中增加一種新的圖像文件格式 TIF,則需要增加 3 個(gè)具體類來(lái)實(shí)現(xiàn)該格式圖像在3種不同操作系統(tǒng)的顯示;如果增加一個(gè)新的操作系統(tǒng) Mac OS,為了在該操作系統(tǒng)下能夠顯示各種類型的圖像,需要增加 4 個(gè)具體類。這將導(dǎo)致系統(tǒng)變得非常龐大,增加運(yùn)行和維護(hù)開銷。
如何解決這兩個(gè)問題?我們通過(guò)分析可得知,該系統(tǒng)存在兩個(gè)獨(dú)立變化的維度:圖像文件格式和操作系統(tǒng),如圖所示:
http://wiki.jikexueyuan.com/project/design-pattern-structurized/images/1334505407_4083.gif" alt="" />
在圖中,如何將各種不同類型的圖像文件解析為像素矩陣與圖像文件格式本身相關(guān),而如何在屏幕上顯示像素矩陣則僅與操作系統(tǒng)相關(guān)。正因?yàn)閳D所示結(jié)構(gòu)將這兩種職責(zé)集中在一個(gè)類中,導(dǎo)致系統(tǒng)擴(kuò)展麻煩,從類的設(shè)計(jì)角度分析,具體類 BMPWindowsImp、BMPLinuxImp 和 BMPUnixImp 等違反了“單一職責(zé)原則”,因?yàn)椴恢挂粋€(gè)引起它們變化的原因,它們將圖像文件解析和像素矩陣顯示這兩種完全不同的職責(zé)融合在一起,任意一個(gè)職責(zé)發(fā)生改變都需要修改它們,系統(tǒng)擴(kuò)展困難。
如何改進(jìn)?我們的方案是將圖像文件格式(對(duì)應(yīng)圖像格式的解析)與操作系統(tǒng)(對(duì)應(yīng)像素矩陣的顯示)兩個(gè)維度分離,使得它們可以獨(dú)立變化,增加新的圖像文件格式或者操作系統(tǒng)時(shí)都對(duì)另一個(gè)維度不造成任何影響。看到這里,大家可能會(huì)問,到底如何在軟件中實(shí)現(xiàn)將兩個(gè)維度分離呢?不用著急,本章我將為大家詳細(xì)介紹一種用于處理多維度變化的設(shè)計(jì)模式——橋接模式。