Java設(shè)計(jì)模式之橋梁(Bridge)模式
橋梁模式的結(jié)構(gòu)
橋梁模式是對(duì)象的結(jié)構(gòu)模式。
如上圖所示,系統(tǒng)含有兩個(gè)等級(jí)結(jié)構(gòu):
- 由抽象化角色和修正抽象化角色組成的抽象化等級(jí)結(jié)構(gòu)。
- 由實(shí)現(xiàn)化角色和兩個(gè)具體實(shí)現(xiàn)化角色所組成的實(shí)現(xiàn)化等級(jí)結(jié)構(gòu)。
橋梁模式所涉及的角色有:
- 抽象化(Abstraction)角色:抽象化給出的定義,并保存一個(gè)對(duì)實(shí)現(xiàn)化對(duì)象的引用。
- 修正抽象(Refined Abstraction)化角色:擴(kuò)展抽象化角色,改變和修正父類對(duì)抽象化的定義。
- 實(shí)現(xiàn)化(Implementor)角色:這個(gè)角色給出實(shí)現(xiàn)化角色的接口,但不給出具體的實(shí)現(xiàn)。必須指出的是,這個(gè)接口不一定和抽象化角色的接口定義相同,實(shí)際上,這兩個(gè)接口可以非常不一樣。 實(shí)現(xiàn)化角色應(yīng)當(dāng)只給出底層操作,而抽象化角色應(yīng)當(dāng)只給出基于底層操作的更高一層的操作。
- 具體實(shí)現(xiàn)化(Concrete Implementor)角色:這個(gè)角色給出實(shí)現(xiàn)化角色接口的具體實(shí)現(xiàn)。
對(duì)象是對(duì)行為的封裝,而行為是由方法實(shí)現(xiàn)的。在這個(gè)示意性系統(tǒng)里,抽象化等級(jí)結(jié)構(gòu)中的類封裝了operation()方法;而實(shí)現(xiàn)化等級(jí)結(jié)構(gòu)中的類封裝的是operationImp()方法。
抽象化等級(jí)結(jié)構(gòu)中的商業(yè)方法通過向?qū)?yīng)的實(shí)現(xiàn)化對(duì)象的委派實(shí)現(xiàn)自己的功能,這意味著抽象化角色可以通過向不同的實(shí)例化對(duì)象委派,來達(dá)到動(dòng)態(tài)地轉(zhuǎn)換自己的功能的目的。
示意性源碼:
抽象化角色,商業(yè)方法operation()的實(shí)現(xiàn)是通過向?qū)崿F(xiàn)化對(duì)象的委派(調(diào)用operationImp()方法)實(shí)現(xiàn)的。
abstract public class Abstraction { protected Implementor imp; /** * 某個(gè)商業(yè)方法 */ public void operation() { imp.operationImp(); } }
修正抽象化角色,商業(yè)方法被置換掉了。
public class RefinedAbstraction extends Abstraction { /** * 某個(gè)商業(yè)方法在修正抽象化角色的實(shí)現(xiàn) */ public void operation() { // improved logic } }
實(shí)現(xiàn)化角色抽象類Implementor中聲明一個(gè)抽象方法operationImp(),這個(gè)方法必須由具體子類實(shí)現(xiàn)。
abstract public class Implementor { /** * 某個(gè)商業(yè)方法的實(shí)現(xiàn)化聲明 */ public abstract void operationImp(); }
具體實(shí)現(xiàn)化角色實(shí)現(xiàn)了抽象類Implementor所聲明的商業(yè)方法operationImp()。
public class ConcreteImplementorA extends Implementor { /** * 某個(gè)商業(yè)方法的實(shí)現(xiàn)化實(shí)現(xiàn) */ public void operationImp() { System.out.println("Do something..."); } }
一般而言,實(shí)現(xiàn)化角色中的每一個(gè)方法都應(yīng)當(dāng)有一個(gè)抽象化角色中的某一個(gè)方法與之相對(duì)應(yīng),但是,反過來則不一定。換言之,抽象化角色的接口比實(shí)現(xiàn)化角色的接口寬。抽象化角色除了提供與實(shí)現(xiàn)化角色相關(guān)的方法之外,還有可能提供其他的商業(yè)方法;而實(shí)現(xiàn)化角色則往往僅為實(shí)現(xiàn)抽象化角色的相關(guān)行為而存在。
例子
空中巴士(Airbus)、波音(Boeing)和麥道(McDonnell-Douglas)都是飛機(jī)制造商,它們都生產(chǎn)載客飛機(jī)(Passenger Plane)和載貨飛機(jī)(Cargo Plane)?,F(xiàn)在需要設(shè)計(jì)一個(gè)系統(tǒng),描述這些飛機(jī)制造商以及它們所制造的飛機(jī)種類。
設(shè)計(jì)方案一
在這個(gè)設(shè)計(jì)方案里,有兩個(gè)子接口:客機(jī)和貨機(jī)。所有的具體飛機(jī)又都要繼承自Airbus,Boeing和MD等超類。這樣一來,每一個(gè)具體飛機(jī)都帶有兩個(gè)超類型:飛機(jī)制造商類型,客、貨機(jī)類型。
這樣設(shè)計(jì)造成具體飛機(jī)與飛機(jī)制造商、飛機(jī)種類之間的耦合過強(qiáng),無法滿足“開-閉原則”:
- 需要向系統(tǒng)引進(jìn)新的飛機(jī)制造商;
- 需要向系統(tǒng)引進(jìn)新的飛機(jī)類型。
設(shè)計(jì)方案二
橋梁模式,抽象化角色——飛機(jī)的種類,實(shí)現(xiàn)化角色——飛機(jī)制造商。
客機(jī)和貨機(jī)經(jīng)過一個(gè)飛機(jī)的“轉(zhuǎn)世”橋梁,可以分別“投胎”到空中巴士、波音和麥道等飛機(jī)制造商哪里,“出生”為不同牌子的飛機(jī)。
由于這個(gè)“轉(zhuǎn)世”橋梁實(shí)際上是一個(gè)聚合關(guān)系,因此可以動(dòng)態(tài)地變化。所以如果系統(tǒng)需要加入新的飛機(jī)種類或者飛機(jī)制造商的話,已有的各個(gè)角色不必改變,需要改變的僅僅是一個(gè)多態(tài)性的聚合關(guān)系。
示意性源代碼:
抽象化角色類Airplane。
abstract public class Airplane { protected AirplaneMaker airplaneMaker; abstract public void fly(); protected Airplane(AirplaneMaker airplaneMaker) { this.airplaneMaker = airplaneMaker; } }
載客飛機(jī)和載貨飛機(jī)屬于修正抽象化角色。
public class PassengerPlane extends Airplane { public void fly() { // Write your code here airplaneMaker.produce(); } public PassengerPlane(AirplaneMaker airplaneMaker) { super(airplaneMaker); } } public class CargoPlane extends Airplane { public void fly() { // Write your code here airplaneMaker.produce(); } public CargoPlane(AirplaneMaker airplaneMaker) { super(airplaneMaker); } }
實(shí)現(xiàn)化角色是飛機(jī)制造商AirplaneMaker,給出修正抽象化角色所需要實(shí)現(xiàn)的接口。
abstract public class AirplaneMaker { abstract public void produce(); }
具體實(shí)現(xiàn)化角色是Airbus、Boeing、MD。
public class Airbus extends AirplaneMaker { public void produce() { // Write your code here System.out.println("produce by Airbus"); } } public class Boeing extends AirplaneMaker { public void produce() { // Write your code here System.out.println("produce by Boeing"); } } public class MD extends AirplaneMaker { public void produce() { // Write your code here System.out.println("produce by MD"); } }
客戶端代碼。
public class BridgePatternDemo { public static void main(String[] args) { Airplane mdPassengerPlane = new PassengerPlane(new MD()); Airplane mdCargoPlane = new CargoPlane(new MD()); mdPassengerPlane.fly(); mdCargoPlane.fly(); Airplane boeingPassengerPlane = new PassengerPlane(new Boeing()); Airplane boeingCargoPlane = new CargoPlane(new Boeing()); boeingPassengerPlane.fly(); boeingCargoPlane.fly(); } }
現(xiàn)在,如果需要增加新的飛機(jī)制造商或者新的飛機(jī)種類,只需要向系統(tǒng)引進(jìn)一個(gè)新的修正抽象化角色或者一個(gè)新的具體實(shí)現(xiàn)化角色即可。即系統(tǒng)的功能可以在不修改已有代碼的情況下得到擴(kuò)展,符合“開-閉”原則。
到此這篇關(guān)于Java設(shè)計(jì)模式之橋梁(Bridge)模式的文章就介紹到這了,更多相關(guān)Java 橋梁模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 23種設(shè)計(jì)模式(10)java組合模式
- 快速理解Java設(shè)計(jì)模式中的組合模式
- JAVA設(shè)計(jì)模式之組合模式原理與用法詳解
- java設(shè)計(jì)模式之組合模式(Composite)
- Java設(shè)計(jì)模式之組合模式(Composite模式)介紹
- 淺談Java設(shè)計(jì)模式之七大設(shè)計(jì)原則
- Java設(shè)計(jì)模式之構(gòu)建者模式知識(shí)總結(jié)
- 詳解java設(shè)計(jì)模式之六大原則
- Java設(shè)計(jì)模式之代理模式詳解
- Java設(shè)計(jì)模式之原型模式詳解
- Java設(shè)計(jì)模式之抽象工廠模式詳解
- 詳細(xì)總結(jié)Java組合模式
相關(guān)文章
java并發(fā)編程中實(shí)現(xiàn)可見性的四種可行方案解析
這篇文章主要介紹了java并發(fā)編程中實(shí)現(xiàn)可見性的四種可行方案解析,使用關(guān)鍵字volatile和使用鎖(如synchronized關(guān)鍵字或者java.util.concurrent包中的鎖)來確保對(duì)共享變量的修改在多線程環(huán)境中能夠正確地被其他線程所觀察到,需要的朋友可以參考下2023-08-08詳解SpringBoot構(gòu)建Docker鏡像的3種方式
這篇文章主要介紹了SpringBoot構(gòu)建Docker鏡像的3種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06Spring Boot使用Servlet及Filter過程詳解
這篇文章主要介紹了Spring Boot使用Servlet及Filter過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07SpringBoot請(qǐng)求處理之常用參數(shù)注解介紹與源碼分析
SpringBoot是一種整合Spring技術(shù)棧的方式(或者說是框架),同時(shí)也是簡(jiǎn)化Spring的一種快速開發(fā)的腳手架,本篇讓我們一起學(xué)習(xí)請(qǐng)求處理、常用注解和方法參數(shù)的小技巧2022-10-10Java中l(wèi)ogback?自動(dòng)刷新不生效的問題解決
本文主要介紹了Java中l(wèi)ogback?自動(dòng)刷新不生效的問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05Java微信公眾平臺(tái)開發(fā)(8) 多媒體消息回復(fù)
這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺(tái)開發(fā)第八步,微信多媒體消息回復(fù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04Java利用自定義注解、反射實(shí)現(xiàn)簡(jiǎn)單BaseDao實(shí)例
下面小編就為大家?guī)硪黄狫ava利用自定義注解、反射實(shí)現(xiàn)簡(jiǎn)單BaseDao實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08