定義:(Mediator Pattern)
用一個(gè)中介對(duì)象封裝一系列的對(duì)象交互,中介者使各對(duì)象不需要顯示地相互作用谋作,從而使耦合松散芋肠,而且可以獨(dú)立地改變它們之間的交互。
類圖:
啟示:
最近兩年瓷们,樓市瘋狂业栅,房?jī)r(jià)漲的離譜。為了預(yù)防樓市泡沫谬晕,中央出臺(tái)一項(xiàng)項(xiàng)政策進(jìn)行調(diào)控碘裕。在這樣一個(gè)現(xiàn)實(shí)場(chǎng)景中,共有三個(gè)角色攒钳,買房者帮孔,房地產(chǎn)商,住建局不撑。
買房者關(guān)注房地廠商的樓盤(pán)及房?jī)r(jià)文兢,決定是否買房;
房地廠商關(guān)注買方市場(chǎng)焕檬,是否需要新建樓盤(pán)姆坚;
住建局就來(lái)協(xié)調(diào)買方與賣方市場(chǎng),限購(gòu)限建实愚。
三個(gè)角色相互依賴兼呵,相互交互兔辅。耦合性比較緊,如何來(lái)解耦呢击喂?中介者來(lái)幫忙维苔。
中介是誰(shuí)呢?就像你去買房懂昂,你肯定找中介啊介时,中介無(wú)所不知,他們即知道房地廠商有哪些樓盤(pán)凌彬,又了解買房市場(chǎng)的需求沸柔,同時(shí)也很熟悉國(guó)家的樓市政策。
代碼:
/// <summary>
/// 抽象角色(模塊)
/// 主要實(shí)現(xiàn)中介的依賴注入
/// </summary>
public abstract class Role
{
protected AbstractMediator mediator;
public Role(AbstractMediator mediator)
{
this.mediator = mediator;
}
}
/// <summary>
/// 購(gòu)房(者)市場(chǎng)
/// </summary>
public class HomeBuyer : Role
{
private readonly string name = "購(gòu)房市場(chǎng):";
public HomeBuyer(AbstractMediator mediator)
: base(mediator)
{
}
private static int requirement = 800;//購(gòu)房需求
public void BuyHouse(int num)
{
string rule = mediator.GetRule();
Console.WriteLine(name + "需要買房:" + num + "套");
if (rule != "LimitBuy")
{
requirement += num;
}
else
{
Console.WriteLine(name + "國(guó)家實(shí)例了限購(gòu)政策饿序,不允許購(gòu)買");
}
}
/// <summary>
/// 簽訂購(gòu)房合同
/// </summary>
/// <param name="num"></param>
public void SignAgreement(int num)
{
requirement -= num;
Console.WriteLine(string.Format("{0}成功購(gòu)房{1}套", name, num));
}
public int GetRequirement()
{
return requirement;
}
}
/// <summary>
/// 房地產(chǎn)商
/// </summary>
public class Builder : Role
{
private readonly string name = "房地產(chǎn)商:";
public Builder(AbstractMediator mediator)
: base(mediator)
{
}
private static int houseNum = 1000;
public void BuildHouse()
{
int requirement = mediator.GetBuyRequirement();
if (houseNum < requirement)
{
//房源不夠勉失,立馬新建
int needBuild = requirement - houseNum + 100;
Console.WriteLine(name + "建房:" + needBuild + "套");
houseNum += needBuild;
}
}
public void SaleHouse(int num)
{
if (houseNum < num)
{
string rule = mediator.GetRule();
if (rule != "LimitBuild")
{
Console.WriteLine(name + "房源不夠,正在建設(shè)中");
this.BuildHouse();
}
}
else
{
houseNum -= num;
Console.WriteLine(name + "賣房:" + num + "套");
//告訴購(gòu)房者簽訂合同
mediator.HomeBuyer.SignAgreement(num);
}
}
public int ShowHouseNum()
{
return houseNum;
}
}
/// <summary>
/// 住建局
/// </summary>
public class ControlCenter : Role
{
public ControlCenter(AbstractMediator mediator)
: base(mediator)
{
}
private readonly string name = "住建局:";
private static string rule;
/// <summary>
/// 當(dāng)需大于供原探,限購(gòu)
/// 當(dāng)供大于需乱凿,限建
/// </summary>
public void Limit()
{
int requirement = mediator.GetBuyRequirement();
int buildingNum = mediator.GetCurrentHouseNumber();
string strs = string.Format("{0}目前購(gòu)房需求為:{1}套;現(xiàn)有房源:{2}套。", name,requirement, buildingNum);
if (requirement > buildingNum)
{
Console.WriteLine(strs + "供小于需咽弦,開(kāi)始實(shí)施限購(gòu)政策");
rule = "LimitBuy";
}
else
{
Console.WriteLine(strs + "供大于需徒蟆,開(kāi)始實(shí)施限建政策");
rule = "LimitBuild";
}
}
public string ShowRule()
{
return rule;
}
/// <summary>
/// 抽象中介,定義各模塊依賴的功能
/// </summary>
public abstract class AbstractMediator
{
/// <summary>
/// 使用屬性注入
/// 因?yàn)橹薪榭赡苤恍枰筒糠纸巧K)交互
/// </summary>
public HomeBuyer HomeBuyer { get; set; }
public Builder HouseBuilder { get; set; }
public ControlCenter ControlCenter { get; set; }
/// <summary>
/// 獲取購(gòu)房需求
/// </summary>
/// <returns></returns>
public abstract int GetBuyRequirement();
/// <summary>
/// 獲取房源數(shù)目
/// </summary>
/// <returns></returns>
public abstract int GetCurrentHouseNumber();
/// <summary>
/// 獲取樓市政策
/// </summary>
/// <returns></returns>
public abstract string GetRule();
}
/// <summary>
/// 具體中介型型,實(shí)現(xiàn)各模塊依賴的功能
/// </summary>
public class Mediator : AbstractMediator
{
public override int GetBuyRequirement()
{
return base.HomeBuyer.GetRequirement();
}
public override int GetCurrentHouseNumber()
{
return base.HouseBuilder.ShowHouseNum();
}
public override string GetRule()
{
return base.ControlCenter.ShowRule();
}
}
class Program
{
static void Main(string[] args)
{
AbstractMediator mediator = new Mediator();
//聲明參與的角色
HomeBuyer buyer = new HomeBuyer(mediator);
Builder build = new Builder(mediator);
ControlCenter center = new ControlCenter(mediator);
//將需要的角色注入到中介
mediator.HouseBuilder = build;
mediator.HomeBuyer = buyer;
mediator.ControlCenter = center;
int initRequirement = mediator.GetBuyRequirement();
int initHousenum = mediator.GetCurrentHouseNumber();
Console.WriteLine(string.Format("目前購(gòu)房需求為:{0}套;現(xiàn)有房源:{1}套段审。", initRequirement, initHousenum));
//買房300套
buyer.BuyHouse(300);
build.SaleHouse(300);
//國(guó)家住建局,考察市場(chǎng)
center.Limit();
//再買房1000套
buyer.BuyHouse(1000);
Console.ReadLine();
}
}
參與角色:
● Mediator 抽象中介者角色
抽象中介者角色定義統(tǒng)一的接口闹蒜,用于各同事角色之間的通信寺枉。
● Concrete Mediator 具體中介者角色
具體中介者角色通過(guò)協(xié)調(diào)各同事角色實(shí)現(xiàn)協(xié)作行為,因此它必須依賴于各個(gè)同事角色绷落。
● Colleague 同事角色
每一個(gè)同事角色都知道中介者角色姥闪,而且與其他的同事角色通信的時(shí)候,一定要通過(guò)中介者角色協(xié)作砌烁。每個(gè)同事類的行為分為兩種:一種是同事本身的行為筐喳,比如改變對(duì)象本身的狀態(tài),處理自己的行為等函喉,這種行為叫做自發(fā)行為(Self-Method)避归,與其他的同事類或中介者沒(méi)有任何的依賴;第二種是必須依賴中介者才能完成的行為管呵,叫做依賴方法(Dep-Method)梳毙。
優(yōu)缺點(diǎn):
優(yōu)點(diǎn):中介者模式的優(yōu)點(diǎn)就是減少類間的依賴,把原有的一對(duì)多的依賴變成了一對(duì)一的依賴捐下,同事類只依賴中介者顿天,減少了依賴堂氯,當(dāng)然同時(shí)也降低了類間的耦合
缺點(diǎn):中介者模式的缺點(diǎn)就是中介者會(huì)膨脹得很大,而且邏輯復(fù)雜牌废,原本N個(gè)對(duì)象直接的相互依賴關(guān)系轉(zhuǎn)換為中介者和同事類的依賴關(guān)系,同事類越多啤握,中介者的邏輯就越復(fù)雜鸟缕。
應(yīng)用場(chǎng)景:
當(dāng)類圖中出現(xiàn)了蜘蛛網(wǎng)狀結(jié)構(gòu)時(shí)一定要考慮使用中介者模式,這有利于把蜘蛛網(wǎng)梳理為星型結(jié)構(gòu)排抬,使原本復(fù)雜混亂的關(guān)系變得清晰簡(jiǎn)單懂从。