用心理解設計模式——中介者模式 / 調停者模式 (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();
}
}
}