C#設計模式(16)——中介者模式

出處:https://www.cnblogs.com/wyy1234/html

 

閱讀目錄網絡

 


1.中介者模式介紹

  中介者模式,定義了一箇中介對象來封裝一系列對象之間的交互關係,中介者使各個對象之間不須要顯式地相互引用,從而下降耦合性。在開發中咱們會遇到各個對象相互引用的狀況,每一個對象均可以和多個對象進行交互,這時將會造成複雜的一對多結構的網狀結構,各個對象之間過分耦合,這樣不利於類的複用和擴展。若是引入了中介者模式,各個對象都經過中介者進行交互,那麼對象之間的關係將變成一對一的星型結構。ide

 

  咱們採用園友LearningHard玩牌的例子來理解中介者模式的用法。在現實生活中,兩我的打牌,若是某我的贏了會影響到對方的狀態。標準中介者模式有抽象中介者角色,具體中介者角色、抽象同事類和具體同事類四個角色,其中打牌的人都是具體的同事類的對象,算帳的平臺是中介者對象。若是此時不採用中介者模式實現的話,則代碼實現打牌的場景以下所示:this

複製代碼
//抽象玩家類
    public abstract class AbstractCardPlayer
    {
        public int MoneyCount { get; set; }
        public AbstractCardPlayer()
        {
            this.MoneyCount = 0;
        }
        public abstract void ChangeCount(int count, AbstractCardPlayer other);
    }
//玩家A類 public class PlayerA : AbstractCardPlayer { public override void ChangeCount(int count, AbstractCardPlayer other) { this.MoneyCount += count; other.MoneyCount -= count; } }
//玩家B類 public class PlayerB : AbstractCardPlayer { public override void ChangeCount(int count, AbstractCardPlayer other) { this.MoneyCount += count; other.MoneyCount -= count; } }

class Program { static void Main(string[] args) { AbstractCardPlayer a = new PlayerA() { MoneyCount = 20 }; AbstractCardPlayer b = new PlayerB() { MoneyCount = 20 }; //玩家a贏了玩家b 5元 Console.WriteLine("a贏了b5元"); a.ChangeCount(5, b); Console.WriteLine($"玩家a如今有{a.MoneyCount}元"); Console.WriteLine($"玩家b如今有{b.MoneyCount}元"); //玩家b贏了玩家a 10元 Console.WriteLine("b贏了a10元"); b.ChangeCount(10, a); Console.WriteLine($"玩家a如今有{a.MoneyCount}元"); Console.WriteLine($"玩家b如今有{b.MoneyCount}元"); Console.ReadKey(); } }
複製代碼

運行結果以下:spa

  上邊的代碼知足了玩牌的功能,可是有一些缺陷:咱們看到上邊栗子中算錢的功能是交給贏家的a.ChangeCount(count, b)方法來實現的,這時是贏家找輸家要錢 贏家a和輸家b是直接通訊的。當玩家比較多的時候,例如a贏了,bcde四個玩家都會輸5元,那麼a就要和bcde玩家都要通訊(多玩家方法改爲:a.ChangeCount(count,b,c,d,e)),如b贏了同理,各個玩家組成了一個複雜的通訊網絡,就像上邊的網狀圖,各個玩家過分耦合。若是咱們引入一箇中間人來負責統一結算,贏家就能夠直接找中間人結算,沒必要直接找全部的輸家要帳了,代碼以下:code

複製代碼
//抽象玩家類
    public abstract class AbstractCardPlayer
    {
        public int MoneyCount { get; set; }
        public AbstractCardPlayer()
        {
            this.MoneyCount = 0;
        }
        public abstract void ChangeCount(int count, AbstractMediator mediator);
    }
    //玩家A類
    public class PlayerA : AbstractCardPlayer
    {
        //經過中介者來算帳,不用直接找輸家了
        public override void ChangeCount(int count, AbstractMediator mediator)
        {
            mediator.AWin(count);
        }
    }
    //玩家B類
    public class PlayerB : AbstractCardPlayer
    {
        public override void ChangeCount(int count, AbstractMediator mediator)
        {
            mediator.BWin(count);
        }
    }
    //抽象中介者
    public abstract class AbstractMediator
    {
        //中介者必須知道全部同事
        public AbstractCardPlayer A;
        public AbstractCardPlayer B;
        public AbstractMediator(AbstractCardPlayer a,AbstractCardPlayer b)
        {
            A = a;
            B = b;
        }
        public abstract void AWin(int count);
        public abstract void BWin(int count);
    }
    //具體中介者
    public class Mediator : AbstractMediator
    {
        public Mediator(AbstractCardPlayer a,AbstractCardPlayer b):base(a,b){}
        public override void AWin(int count)
        {
            A.MoneyCount += count;
            B.MoneyCount -= count;
        }
        public override void BWin(int count)
        {
            A.MoneyCount -= count;
            B.MoneyCount += count;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            AbstractCardPlayer a = new PlayerA() { MoneyCount = 20 };
            AbstractCardPlayer b = new PlayerB() { MoneyCount = 20 };
            AbstractMediator mediator = new Mediator(a, b);
            //玩家a贏了玩家b 5元
            Console.WriteLine("a贏了b5元");
            a.ChangeCount(5, mediator);
            Console.WriteLine($"玩家a如今有{a.MoneyCount}元");
            Console.WriteLine($"玩家b如今有{b.MoneyCount}元");
            //玩家b贏了玩家a 10元
            Console.WriteLine("b贏了a10元");
            b.ChangeCount(10, mediator);
            Console.WriteLine($"玩家a如今有{a.MoneyCount}元");
            Console.WriteLine($"玩家b如今有{b.MoneyCount}元");
            Console.ReadKey();
        }
    }
複製代碼

  運行結果和不用中介者的例子一致。咱們能夠看到中介者模式下降了各個同事對象的耦合,同事類之間不用直接通訊,直接找中介者就好了,可是中介者模式並無下降業務的複雜度,中介者將同事類間的複雜交互邏輯從業務代碼中轉移到了中介者類的內部。標準中介者模式有抽象中介者角色,具體中介者角色、抽象同事類和具體同事類四個角色,在實際開發中有時候不必對具體中介者角色和具體用戶角色進行抽象(如聯合國做爲一箇中介者,負責調停各個國家糾紛,可是不必把單獨的聯合國抽象成一個抽象中介者類;上邊例子的抽象玩家類和抽象中介者類都是不必的),咱們能夠根據具體的狀況來來選擇是否使用抽象中介者和抽象用戶角色。htm

2.小結

1.上邊例子的類圖對象

中介者模式優勢:blog

  1 下降了同事類交互的複雜度,將一對多轉化成了一對一;開發

  2 各個類之間的解耦;

  3 符合迪米特原則。

中介者模式缺點:

  1 業務複雜時中介者類會變得複雜難以維護。

 

參考文獻

 [1] http://www.runoob.com/design-pattern/mediator-pattern.html

 [2] http://www.cnblogs.com/zhili/p/MediatorPattern.html

相關文章
相關標籤/搜索