在學(xué)習(xí)這個(gè)設(shè)計(jì)模式的時(shí)候,我是比較痛苦的。因?yàn)榫W(wǎng)上的很多教程雖然主題是橋(Bridge),但是一直在說如何拆分,如何解耦。直到我真正理解橋接模式之后,才發(fā)現(xiàn)那些教程都背離了這一設(shè)計(jì)模式的名字---Bridge,即一個(gè)起到連接作用的物體。
橋接的是什么?
試想有這樣一個(gè)類層次結(jié)構(gòu),它實(shí)現(xiàn)的是類的意義層面上的抽象:

另外還有一個(gè)接口層次結(jié)構(gòu),而它表示的則是從類的行為層面進(jìn)行抽象:

為了讓兩者能夠松耦合地運(yùn)行在一起,通過在Shape中添加DrawingProgramming的實(shí)例的方式進(jìn)行聚合,即實(shí)現(xiàn)了橋接模式:

橋接模式
一般來說,橋接模式可以概括為下圖:

可以看到圖中共有5個(gè)主要的概念:
- Client: 客戶端,對類進(jìn)行調(diào)用;
- Abstraction:抽象類,從類的實(shí)際含義角度出發(fā),對其進(jìn)行抽象,并包含一個(gè)Implementor的實(shí)例
- Implementor:實(shí)現(xiàn)者,一般是一個(gè)定義了類的各種行為的接口;
- RefinedAbstraction:細(xì)化類,擴(kuò)展(extends)了Abstraction,從類的含義上進(jìn)行結(jié)構(gòu)的堆疊;
- ConcreteImplementor A&B:具體實(shí)現(xiàn),即實(shí)現(xiàn)了Implementor中定義的方法,提供類的行為的具體內(nèi)容。
其實(shí)看到這個(gè)圖之后,有的人可能會(huì)提出異議:
為什么不直接將Implementor中定義的方法放入Abstraction,然后讓RefinedAbstraction直接實(shí)現(xiàn)呢?
單一責(zé)任原則
單一責(zé)任原則(SRP:Single responsibility principle)又稱單一職責(zé)原則,如果一個(gè)類承擔(dān)的責(zé)任過多,就等于把這些責(zé)任耦合在一起了。一個(gè)責(zé)任的變化可能會(huì)影響這個(gè)類完成其他責(zé)任的能力。這種耦合會(huì)導(dǎo)致脆弱的設(shè)計(jì),當(dāng)發(fā)生變更時(shí),設(shè)計(jì)會(huì)遭受到意想不到的破壞。
SRP正是橋接模式要維護(hù)的原則。試問如果真的將方法放入Abstraction后,它的子類將會(huì)為了實(shí)現(xiàn)放入父類的方法而絞盡腦汁,盡管很可能某個(gè)方法和某個(gè)子類沒有任何關(guān)系;而如果不把大部分子類的行為方法抽象到父類中,又會(huì)導(dǎo)致類型之間的不兼容,引發(fā)了大量的instanceof海洋(instance of ocean)。

橋接模式的優(yōu)點(diǎn)
使用橋接模式,主要是看中了它所帶來的優(yōu)點(diǎn):
- 將類的含義層次和行為層次松耦合;
- 使整套API能夠擁有兩個(gè)維度的擴(kuò)展鏈,提到了系統(tǒng)的獨(dú)立性;
- 隱藏了更多的細(xì)節(jié);
- 使用設(shè)計(jì)模式能夠使其他開發(fā)維護(hù)者更容易理解。
使用范例
從下圖中我們可以看出,Shape和DrawAPI很好地解耦了,Circle從類的含義出發(fā)進(jìn)行了擴(kuò)展,而RedCircle和GreenCircle從類的行為出發(fā)進(jìn)行了接口的實(shí)現(xiàn),兩者互不影響,且通過一個(gè)聚合的關(guān)系,將兩個(gè)維度松耦合到了一起。
