設計模式之中介者

中介者模式介紹

中介者模式

中介者模式是一種行為設計模式,能讓你減少對象之間混亂無序的依賴關係,該模式會限制對象之間的直接交互,迫使它們通過一個中介者對象進行合作。

中介者模式顧名思義,可以用我們平時生活中的房產中介去理解。房產中介就是房子擁有者和想買房子人直接的橋樑,不讓二者直接交易,通過中介去做橋樑,進行溝通和交易。

中介者模式建議你停止組件之間的直接交流並使其相互獨立。這些組件必須調用特殊的中介者對象,通過中介者對象重定向調用行為,以間接的方式進行合作。最終,組件僅依賴於一個中介者類,無需與多個組件想耦合。

類所擁有的依賴關係越少,就越易於修改、擴展或復用。

可以為所有類型的對話框抽取通用接口,進一步消弱其依賴性;接口中將聲明一個所有表單元素都能使用的通知方法,可用於將元素中發生的事件通知給對話框,所有實現了該接口的對話框都能使用這個提交按鈕。

中介者模式結構

  • 1、組件

是包含業務邏輯的類。每一個組件都有一個指向中介者的引用,該引用被聲明為中介者接口類型。組件並不知道中介者所屬的類,這樣就可通過將其連接到不同的中介者使其能在其他程序中復用。

  • 2、中介租接口

聲明了與組件交流的方法,但通常僅包括一個通知方法。組件可將任意上下文(自身)作為該方法的參數,只有這樣接收組件和發送者類之間才不會耦合。

  • 3、具體中介者

封裝了多種組件間的關係。具體中介者通常會保存所有組件的引用並對其進行管理,甚至有時會對其生命周期進行管理。

  • 4、通知邏輯

組件並不知道其他組件的情況。如果組件內發生了重要事情,它只能通知中介者。中介者收到消息後能輕易地確定發送者,者或許已足以去判斷接下來需要觸發的組件。

對於組件來說,中介者其實就是一個黑箱。發送者不知道最終會由誰來處理自己的請求,接收者也不知道最初的誰發出了請求。

適用場景

  • 1 當某些對象和其他對象緊密耦合難以進行修改時
  • 2 一個組件過於依賴其他組件而無法在不同應用中復用時
  • 3 為了能在不同情景下復用一些基本行為,導致你需要被迫場景大量組件子類時

實現方式

  • 找到一組當前緊密耦合的類且提供其獨立性能帶來更大好處的類。
  • 聲明中介者接口並描述中介者和各種組件之間所需的交流接口(一個接收組件的方法就夠了)。
  • 實現具體中介者類。
  • 讓中介者負責組件對象的創建和銷毀。
  • 組件必須保存對於中介對象的引用。
  • 修改組件代碼,使其可調用中介者的通知方法,而非其他組件的方法。然後將調用其他組件的代碼抽取到中介者類中,並在中介者接收到該組件通知時執行這些代碼。

滿足單一職責、開閉原則、減輕應用中多個組件間的耦合情況、方便復用各個組件。

中介者將系統中組件的溝通行為中心化。各組件只知道中介者對象,無法直接相互交流。

中介者的主要目標時消除一系列系統組件之間的相互依賴。這些組件將依賴於同一個中介者對象。

Demo

中介接口和房產鏈家

    /// <summary>
    /// 房產中介接口
    /// </summary>
    public interface IHouseMediator 
    {
        void Notify(object sneder,string ev);
    }
    /// <summary>
    /// 鏈家   房產中介。實現房產中介接口
    /// </summary>
    class LianJiaMediator :IHouseMediator
    {
        private TianJingHouse _tjHouse;
        private XianAnHouse _xaHouse;        

        public LianJiaMediator(TianJingHouse houseTj, XianAnHouse houseXa)
        {                        
            this._tjHouse = houseTj;
            this._tjHouse.SetHouseMediator(this);

            this._xaHouse = houseXa;
            this._xaHouse.SetHouseMediator(this);
        }

        public void Notify(object sneder, string ev)
        {
            if (ev == "FirstTJ")
            {
                Console.WriteLine("輸出......");
                this._xaHouse.SecondSell();
            }

            if (ev == "SecondXA")
            {
                Console.WriteLine("輸出------");
                this._tjHouse.SecondSell();
                this._xaHouse.SecondSell();
            }
        }
    }

房子基類和 將售賣的房子

    /// <summary>
    /// 房子基類
    /// </summary>
    class BaseHouse 
    {
        protected IHouseMediator _houseMediator;
        
        public BaseHouse(IHouseMediator houseMediator=null)
        {
            this._houseMediator = houseMediator;
        }

        public void SetHouseMediator(IHouseMediator houseMediator) 
        {
            this._houseMediator = houseMediator;
        }
    }

    /// <summary>
    /// 天津的房子
    /// </summary>
    class TianJingHouse :BaseHouse
    {
        public void FirstSell() 
        {
            Console.WriteLine("天津房子第一次出售");
            this._houseMediator.Notify(this, "FirstTJ");
        }

        public void SecondSell()
        {
            Console.WriteLine("天津房子第二次出售");
            this._houseMediator.Notify(this, "SecondTJ");
        }
    }

    /// <summary>
    /// 西安的房子
    /// </summary>
    class XianAnHouse : BaseHouse 
    {
        public void FirstSell()
        {
            Console.WriteLine("西安房子第一次出售");
            this._houseMediator.Notify(this, "FirstXA");
        }

        public void SecondSell()
        {
            Console.WriteLine("西安房子第二次出售");
            this._houseMediator.Notify(this, "SecondXA");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            TianJingHouse tjHouse = new TianJingHouse();
            XianAnHouse xiHouse = new XianAnHouse();
            new LianJiaMediator(tjHouse, xiHouse);

            Console.WriteLine("客戶端 執行First TJ");
            tjHouse.FirstSell();

            Console.ReadLine();

            Console.WriteLine("客戶端 執行Second XA");
            xiHouse.SecondSell();
            
            Console.ReadKey();
        }
    }

小寄語

人生短暫,我不想去追求自己看不見的,我只想抓住我能看的見的。

原創不易,給個關注。

我是阿輝,感謝您的閱讀,如果對你有幫助,麻煩關注、點贊、轉發 謝謝。