1. 程式人生 > >用心理解設計模式——中介者模式 / 調停者模式 (Mediator Pattern)

用心理解設計模式——中介者模式 / 調停者模式 (Mediator Pattern)

前置文章: 用心理解設計模式——設計模式的原則 

設計模式相關程式碼已統一放至 我的 Github

 

一、定義

  行為型模式之一。

Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to referring to each other explicitly, and it lets you vary their interaction independently.

(定義一個物件,用於封裝一組物件的互動。中介者通過防止物件顯式地引用彼此,來提升耦合鬆散度,並且允許你獨立地更改它們之間的互動。)

二、結構解析

  中介者模式的一般結構有四種角色:抽象同事、真實同事、抽象中介者、具體中介者。

  抽象同事,負責定義和持有抽象型別中介者,可定義一個方法,宣告 “中介者和同事將在此方法中與進行互動”。

  具體同事,確定具體中介者,當好螺絲釘,只做自己應做的事。根據自己需要的輸入資源,產出自己應產出的產品。

  抽象中介者,負責為每個具體同事提供需要什麼資源產出什麼產品的介面方法。可為客戶端定義一個獲得最終產品的介面。

  具體中介者,實現抽象中介者定義的介面方法,負責具體協調邏輯,確定每個具體同事所需資源的組成,確定每個具體同事的產出去向,決定最終產品的組成。

三、評價

  中介者模式,作為行為型模式之一,它將 “中介/協調/調停” 這個抽象概念抽象為類。並定義了多個同事(有上下游資源依賴、協作等關係)之間一起工作、互動時,由 “中介” 進行協調的行為過程。讓具體同事之間的耦合得以解除,每個具體同事都只與中介者進行互動,然後各司其職。它把同事間的多對多的網狀互動,變成一對多,“一”指中介者。

  新增具體同事較方便,同時,需要修改抽象中介者,修改或新增具體中介者。

四、實現

using System.Collections.Generic;

namespace Mediator
{
    //輔助測試引數類
    public class ARes { }
    public class AProduct { }
    public class BRes { }
    public class BProduct { }
    public class CRes { }
    public class CProduct { }
    public class FinalProduct { }

    //抽象中介者類
    public abstract class Mediator
    {
        //對具體同事A提供的介面,需要什麼、產出什麼
        public abstract ARes GetARes();
        public abstract void OutputAProduct(AProduct aProduct);

        //對具體同事A提供的介面,需要什麼、產出什麼
        public abstract BRes GetBRes();
        public abstract void OutputBProduct(BProduct bProduct);

        //對具體同事A提供的介面,需要什麼、產出什麼
        public abstract CRes GetCRes();
        public abstract void OutputCProduct(CProduct cProduct);

        public abstract FinalProduct GetFinalProduct();
    }

    //抽象同事類
    public abstract class Colleague
    {
        //持有中介者,只和中介者互動
        protected Mediator mediator;
        public Colleague(Mediator mediator)
        {
            this.mediator = mediator;
        }

        //抽象介面,做自己的事,在這個方法中,從中介者拿到所需資源,生產,然後將產品交給中介者。
        public abstract void DoSelfDuty();
    }

    //具體同事A
    public class ConcreteColleagueA : Colleague
    {
        //建構函式,至少需要傳入中介者
        public ConcreteColleagueA(Mediator mediator) : base(mediator) { }

        public override void DoSelfDuty()
        {
            //從中介者拿到所需資源
            ARes aRes = this.mediator.GetARes();
            //生產
            AProduct aProduct = ProcessA(aRes);
            //將產品交給中介者
            this.mediator.OutputAProduct(aProduct);
        }

        private AProduct ProcessA(ARes aRes)
        {
            //這裡簡略了資源變為產品的加工過程
            return new AProduct();
        }
    }

    //具體同事B
    public class ConcreteColleagueB : Colleague
    {
        public ConcreteColleagueB(Mediator mediator) : base(mediator) { }

        public override void DoSelfDuty()
        {
            BRes bRes = this.mediator.GetBRes();
            BProduct bProduct = ProcessB(bRes);
            this.mediator.OutputBProduct(bProduct);
        }

        private BProduct ProcessB(BRes bRes)
        {
            return new BProduct();
        }
    }

    //具體同事C
    public class ConcreteColleagueC : Colleague
    {
        public ConcreteColleagueC(Mediator mediator) : base(mediator) { }

        public override void DoSelfDuty()
        {
            CRes cRes = this.mediator.GetCRes();
            CProduct cProduct = ProcessC(cRes);
            this.mediator.OutputCProduct(cProduct);
        }

        private CProduct ProcessC(CRes cRes)
        {
            return new CProduct();
        }
    }

    //具體中介者類, 負責具體協調邏輯。
    public class ConcreteMediator : Mediator
    {
        //示例,產品或半成品倉庫,快取具體同事ABC的產出。ABC所需的資源也可從這裡拿,最終產品所需的資源也可以從這裡拿。
        protected List<AProduct> aProductList = new List<AProduct>();
        protected List<BProduct> bProductList = new List<BProduct>();
        protected List<CProduct> cProductList = new List<CProduct>();

        public override ARes GetARes()
        {
            //這裡簡略ARes的產生過程,這裡可以決定A所需的資源由什麼組成
            return new ARes();
        }

        public override BRes GetBRes()
        {
            //這裡簡略BRes的產生過程,這裡可以決定B所需的資源由什麼組成
            return new BRes();
        }

        public override CRes GetCRes()
        {
            //這裡簡略CRes的產生過程,這裡可以決定C所需的資源由什麼組成
            return new CRes();

            //例如: CRes可能由AProduct和BProduct兩種半成品組成, 需要同時在CRes中提供對應的建構函式
            //return new CRes(aProductSet[0], bProductSet[0]);
        }

        //A產出的產品放入快取倉庫
        public override void OutputAProduct(AProduct aProduct)
        {
            aProductList.Add(aProduct);
        }

        //B產出的產品放入快取倉庫
        public override void OutputBProduct(BProduct bProduct)
        {
            bProductList.Add(bProduct);
        }

        //C產出的產品放入快取倉庫
        public override void OutputCProduct(CProduct cProduct)
        {
            cProductList.Add(cProduct);
        }

        //最終產品,提供給客戶端的介面
        public override FinalProduct GetFinalProduct()
        {
            //這裡簡略FinalProduct的產生過程。
            //這裡可以決定最終產品所需的資源由什麼組成。
            //可能ABC其中的某個產品就是最終產品,也可能由ABC的半成品組成,但是這個組成過程也可以擴充套件一個D並且放到D中去。最終讓某個具體同事類的產品作為最終產品。
            return new FinalProduct();
        }
    }

    public class Client
    {
        static public void Main()
        {
            //構建具體類
            ConcreteMediator concreteMediator = new ConcreteMediator();
            ConcreteColleagueA concreteColleagueA = new ConcreteColleagueA(concreteMediator);
            ConcreteColleagueB concreteColleagueB = new ConcreteColleagueB(concreteMediator);
            ConcreteColleagueC concreteColleagueC = new ConcreteColleagueC(concreteMediator);

            //各司其職
            concreteColleagueA.DoSelfDuty();
            concreteColleagueB.DoSelfDuty();
            concreteColleagueC.DoSelfDuty();

            //得到最終產品
            FinalProduct finalProduct = concreteMediator.GetFinalProduct();
        }
    }
}