橋接模式 - 設計模式學習

  合成/聚合複用原則(CARP),儘可能使用合成/聚合,儘可能不要使用類繼承。javascript

  合成和聚合都是關聯的特殊種類。聚合表示一種弱的「擁有關係」,體現的是A對象能夠包含B對象,但B對象不必定是A對象的一部分;合成則是一種槍的‘擁有’關係,體現了嚴格的部分和總體的關係,部分和總體的聲明週期同樣。比方說,大雁有兩個翅膀,翅膀與大雁是部分和總體的關係,而且它們的聲明週期是相同的,因而大雁和翅膀就是合成關係。而大雁是羣居動物,因此每隻大雁都是屬於一個雁羣,一個雁羣能夠有多隻大雁,因此大雁和雁羣是聚合關係。html

  合成/聚合複用原則的好處是,有限使用對象的合成/聚合將有助於你保持每一個類被封裝,並被集中在單個任務上。這樣類和類繼承層次會保持較小規模,而且不太可能增加爲不可控制的龐然大物。java

  橋接模式(Bridge),將抽象部分與它的實現部分分離,使它們均可以獨立地變化。git

  什麼叫抽象與它的實現分離,這並非說,讓抽象類與其派生類分離,由於這沒有任何意義。實現指的是抽象類和它的派生類用來實現本身的對象。橋接模式主要講的是儘可能用聚合,而不要盲目使用繼承。設計模式

  下面給出橋接模式的UML圖:ide

    

  橋接模式的基本代碼結構:post

複製代碼
namespace ConsoleApplication1
{
    abstract class Implementor
    {
        public abstract void Operation();
    }

    class ConcreteImplementorA : Implementor
    {
        public override void Operation()
        {
            Console.WriteLine("具體實現A的方法執行");
        }
    }

    class ConcreteImplementorB : Implementor
    {
        public override void Operation()
        {
            Console.WriteLine("具體實現B的方法執行");
        }
    }

    class Abstraction
    {
        protected Implementor implementor;

        public void SetImplementor(Implementor implementor)
        {
            this.implementor = implementor;
        }

        public virtual void Operation()
        {
            implementor.Operation();
        }
    }

    class RefinedAbstraction : Abstraction 
    {
        public override void Operation()
        {
            implementor.Operation();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Abstraction ab = new RefinedAbstraction();

            ab.SetImplementor(new ConcreteImplementorA());
            ab.Operation();

            ab.SetImplementor(new ConcreteImplementorB());
            ab.Operation();

            Console.ReadKey();
        }
    }  
}
複製代碼

  結果:學習

  

   實現系統可能有多角度分類,每一種分那麼類都有可能變化,那麼就把這種多角度分離出來讓它們獨立變化,減小它們之間的耦合。this

   其實只要真正瞭解設計原則,不少設計模式其實就是原則的應用而已,或許在不知不覺中就在使用設計模式了。spa

   如今回到《大話設計模式》中的手機品牌與軟件的例子

複製代碼
namespace ConsoleApplication1
{
    //手機軟件抽象類
    abstract class HandsetSoft
    {
        public abstract void Run();
    }

    //手機遊戲
    class HandsetGame : HandsetSoft 
    {
        public override void Run()
        {
            Console.WriteLine("運行手機遊戲");
        }
    }

    //手機通信錄
    class HandsetAddressList : HandsetSoft
    {
        public override void Run()
        {
            Console.WriteLine("運行和蒐集通信錄");
        }
    }

    //手機品牌抽象類
    abstract class HandsetBrand
    {
        protected HandsetSoft soft;

        //設置手機軟件
        public void SetHandsetSoft(HandsetSoft soft)    //品牌須要關注軟件,因此可在機器中安裝軟件(設置手機軟件),以備運行
        {
            this.soft = soft;
        }

        //運行
        public abstract void Run();
    }

    //手機品牌N
    class HandsetBrandN : HandsetBrand
    {
        public override void Run()
        {
            soft.Run();
        }
    }

    //手機品牌M
    class HandsetBrandM : HandsetBrand
    {
        public override void Run()
        {
            soft.Run();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            HandsetBrand ab;
            ab = new HandsetBrandN();

            ab.SetHandsetSoft(new HandsetGame());
            ab.Run();

            ab.SetHandsetSoft(new HandsetAddressList());
            ab.Run();

            ab = new HandsetBrandM();

            ab.SetHandsetSoft(new HandsetGame());
            ab.Run();

            ab.SetHandsetSoft(new HandsetAddressList());
            ab.Run();

            Console.ReadKey();
        }
    }  
}
複製代碼

  這樣寫的好處很是好,若是如今要增長一個功能,例如MP3音樂播放功能,那麼只要增長一個MP3音樂播放類就能夠了。

  在《大話設計模式》中有一個用繼承的寫法,如今放上它的類圖:

  

  在這種用繼承的方法,就增長一個MP3音樂播放功能,那就須要在每一個品牌下添加一個MP3音樂播放類,若是須要再添加一個手機品牌,也有通信錄,遊戲,MP3播放器功能,那就須要添加至關多的類,崩潰。

  可是上面的橋接模式的類圖:

  

  手機品牌與手機軟件之間是聚合關係,當須要添加一個MP3音樂播放功能時,只須要添加一個類,而須要添加一個手機品牌時,也只是須要添加一個類。

 
 
分類: 設計模式
 
0
0
 
(請您對文章作出評價)
 
« 上一篇: 迭代器模式 - 設計模式學習
» 下一篇: 命令模式 - 設計模式學習
相關文章
相關標籤/搜索