溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何理解Java設(shè)計(jì)模式的橋接模式

發(fā)布時(shí)間:2021-11-08 10:39:17 來源:億速云 閱讀:157 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“如何理解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)

    如何理解Java設(shè)計(jì)模式的橋接模式

    在橋接模式結(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ù)操作方法。

    三、橋接模式的使用場(chǎng)景

    • 當(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)

    優(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)。

    六、橋接模式的實(shí)現(xiàn)

    首先抽象出電視機(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)注!

    向AI問一下細(xì)節(jié)

    免責(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)容。

    AI