您好,登錄后才能下訂單哦!
這篇文章主要講解了“如何理解Java設(shè)計(jì)模式的橋接模式”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“如何理解Java設(shè)計(jì)模式的橋接模式”吧!
橋接模式(Bridge Pattern
):將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。它是一種對(duì)象結(jié)構(gòu)型模式,又稱為柄體(Handle and Body
)模式或接口(Interface
)模式。
在橋接模式結(jié)構(gòu)圖中包含如下幾個(gè)角色:
Abstraction
(抽象類):用于定義抽象類的接口,它一般是抽象類而不是接口,其中定義了一個(gè)Implementor(實(shí)現(xiàn)類接口)類型的對(duì)象并可以維護(hù)該對(duì)象,它與Implementor之間具有關(guān)聯(lián)關(guān)系,它既可以包含抽象業(yè)務(wù)方法,也可以包含具體業(yè)務(wù)方法。
RefinedAbstraction
(擴(kuò)充抽象類):擴(kuò)充由Abstraction定義的接口,通常情況下它不再是抽象類而是具體類,它實(shí)現(xiàn)了在Abstraction中聲明的抽象業(yè)務(wù)方法,在RefinedAbstraction中可以調(diào)用在Implementor中定義的業(yè)務(wù)方法。
Implementor
(實(shí)現(xiàn)類接口):定義實(shí)現(xiàn)類的接口,這個(gè)接口不一定要與Abstraction的接口完全一致,事實(shí)上這兩個(gè)接口可以完全不同,一般而言,Implementor接口僅提供基本操作,而Abstraction定義的接口可能會(huì)做更多更復(fù)雜的操作。Implementor接口對(duì)這些基本操作進(jìn)行了聲明,而具體實(shí)現(xiàn)交給其子類。通過關(guān)聯(lián)關(guān)系,在Abstraction中不僅擁有自己的方法,還可以調(diào)用到Implementor中定義的方法,使用關(guān)聯(lián)關(guān)系來替代繼承關(guān)系。
ConcreteImplementor
(具體實(shí)現(xiàn)類):具體實(shí)現(xiàn)Implementor接口,在不同的ConcreteImplementor中提供基本操作的不同實(shí)現(xiàn),在程序運(yùn)行時(shí),ConcreteImplementor對(duì)象將替換其父類對(duì)象,提供給抽象類具體的業(yè)務(wù)操作方法。
當(dāng)對(duì)象存在多種變化的因素時(shí),考慮對(duì)其變化的因素和場(chǎng)景進(jìn)行抽象,然后進(jìn)行橋接;如筆擁有不同的功能。
當(dāng)多個(gè)對(duì)象存在多種變化的因素時(shí),考慮將這部分變化的部分抽象出來再聚合進(jìn)來;比如不同品牌的電腦安裝不同的系統(tǒng)、使用不同的軟件等,相當(dāng)于將第一條進(jìn)行橫向擴(kuò)展,增加橋接的數(shù)量。
優(yōu)點(diǎn):
(1)分離抽象接口及其實(shí)現(xiàn)部分。橋接模式使用“對(duì)象間的關(guān)聯(lián)關(guān)系”解耦了抽象和實(shí)現(xiàn)之間固有的綁定關(guān)系,使得抽象和實(shí)現(xiàn)可以沿著各自的維度來變化。所謂抽象和實(shí)現(xiàn)沿著各自維度的變化,也就是說抽象和實(shí)現(xiàn)不再在同一個(gè)繼承層次結(jié)構(gòu)中,而是“子類化”它們,使它們各自都具有自己的子類,以便任何組合子類,從而獲得多維度組合對(duì)象。
(2)在很多情況下,橋接模式可以取代多層繼承方案,多層繼承方案違背了“單一職責(zé)原則”,復(fù)用性較差,且類的個(gè)數(shù)非常多,橋接模式是比多層繼承方案更好的解決方法,它極大減少了子類的個(gè)數(shù)。
(3)橋接模式提高了系統(tǒng)的可擴(kuò)展性,在兩個(gè)變化維度中任意擴(kuò)展一個(gè)維度,都不需要修改原有系統(tǒng),符合“開閉原則”。
缺點(diǎn):
(1)橋接模式的使用會(huì)增加系統(tǒng)的理解與設(shè)計(jì)難度,由于關(guān)聯(lián)關(guān)系建立在抽象層,要求開發(fā)者一開始就針對(duì)抽象層進(jìn)行設(shè)計(jì)與編程。
(2)橋接模式要求正確識(shí)別出系統(tǒng)中兩個(gè)獨(dú)立變化的維度,因此其使用范圍具有一定的局限性,如何正確識(shí)別兩個(gè)獨(dú)立維度也需要一定的經(jīng)驗(yàn)積累。
三者都是結(jié)構(gòu)型的設(shè)計(jì)模式,而且都存在依賴抽象的情況
重點(diǎn)強(qiáng)調(diào)的是適配的功能。(適配器依賴抽象)
關(guān)鍵點(diǎn)是:
主體類和適配器類實(shí)現(xiàn)相同的接口A
主體類依賴適配器類
適配器類依賴抽象接口B
被適配的類實(shí)現(xiàn)抽象接口B
最終的效果就是,主體類可以使用之前不相關(guān)的被適配類中的某些功能。
重點(diǎn)強(qiáng)調(diào)的是多維度的變化。(主體類直接依賴抽象)
關(guān)鍵點(diǎn)是:
主體類依賴抽象A
主體類具有多個(gè)不同的實(shí)現(xiàn)類
抽象A具有多個(gè)不同的實(shí)現(xiàn)類
最終的效果就是,主體類的實(shí)現(xiàn)類和抽象的實(shí)現(xiàn)類分別可以在兩個(gè)維度上進(jìn)行各自的變化。如果主體類依賴多個(gè)抽象,則維度進(jìn)行增加,方便擴(kuò)展。
重點(diǎn)強(qiáng)調(diào)的是裝飾功能。(主體類不僅依賴抽象,而且實(shí)現(xiàn)該抽象接口)
關(guān)鍵點(diǎn)是:
抽象A具有多個(gè)具體子類
裝飾器類依賴抽象A
裝飾器類實(shí)現(xiàn)抽象A
裝飾器類存在不同子類
最終的效果就是,(裝飾器實(shí)現(xiàn)類)對(duì)(原抽象的子類)進(jìn)行某些方法的功能加強(qiáng)。
首先抽象出電視機(jī),提供遙控器改變的行為方法。
/// <summary> /// 電視機(jī),提供抽象方法 /// </summary> public abstract class TV { public abstract void On(); public abstract void Off(); public abstract void tuneChannel(); }
創(chuàng)建具體的電視機(jī),繼承自抽象電視機(jī)類:
/// <summary> /// 三星牌電視機(jī),重寫基類的抽象方法 /// </summary> public class Samsung:TV { public override void On() { Console.WriteLine("三星牌電視機(jī)已經(jīng)打開了"); } public override void Off() { Console.WriteLine("三星牌電視機(jī)已經(jīng)關(guān)掉了"); } public override void tuneChannel() { Console.WriteLine("三星牌電視機(jī)換頻道"); } } /// <summary> /// 長(zhǎng)虹牌電視機(jī),重寫基類的抽象方法 /// 提供具體的實(shí)現(xiàn) /// </summary> public class ChangHong : TV { public override void On() { Console.WriteLine("長(zhǎng)虹牌電視機(jī)已經(jīng)打開了"); } public override void Off() { Console.WriteLine("長(zhǎng)虹牌電視機(jī)已經(jīng)關(guān)掉了"); } public override void tuneChannel() { Console.WriteLine("長(zhǎng)虹牌電視機(jī)換頻道"); } }
然后抽象出概覽中的遙控器,扮演抽象話的角色
/// <summary> /// 抽象概念中的遙控器,扮演抽象化角色 /// </summary> public abstract class RemoteControl { public TV implementor { get; set; } /// <summary> /// 開電視機(jī) /// 這里抽象類中不再提供實(shí)現(xiàn)了,而是調(diào)用實(shí)現(xiàn)類中的實(shí)現(xiàn) /// </summary> public virtual void On() { implementor.On(); } /// <summary> /// 關(guān)電視機(jī) /// </summary> public virtual void Off() { implementor.Off(); } /// <summary> /// 換頻道 /// </summary> public virtual void SetChannel() { implementor.tuneChannel(); } }
創(chuàng)建具體遙控器類:這里面,我重寫了更換頻道的方法,其實(shí)還可以重寫其他的方法
/// <summary> /// 具體遙控器類 /// </summary> public class ConcreteRemote:RemoteControl { /// <summary> /// 重寫更換頻道方法 /// </summary> public override void SetChannel() { Console.WriteLine("重寫更換頻道方法"); base.SetChannel(); } }
客戶端代碼:
static void Main(string[] args) { // 創(chuàng)建一個(gè)遙控器 RemoteControl remoteControl = new ConcreteRemote(); //長(zhǎng)虹電視機(jī) remoteControl.implementor = new ChangHong(); remoteControl.On(); remoteControl.SetChannel(); remoteControl.Off(); Console.WriteLine(); // 三星牌電視機(jī) remoteControl.implementor = new Samsung(); remoteControl.On(); remoteControl.SetChannel(); remoteControl.Off(); Console.Read(); }
這樣接實(shí)現(xiàn)了橋接模式的設(shè)計(jì),遙控器的功能實(shí)現(xiàn)方法不是在遙控器中去實(shí)現(xiàn)了,而是將實(shí)現(xiàn)部分用來另一個(gè)電視機(jī)類去封裝它,遙控器中只包含電視機(jī)類的一個(gè)引用,通過橋接模式,我們把抽象化和實(shí)現(xiàn)化部分分離開了,這樣可以很好應(yīng)對(duì)這兩方面的變化。
感謝各位的閱讀,以上就是“如何理解Java設(shè)計(jì)模式的橋接模式”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)如何理解Java設(shè)計(jì)模式的橋接模式這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。