深入理解Java設(shè)計(jì)模式之中介者模式
一、什么是中介者模式
用一個(gè)中介對(duì)象來(lái)封裝一系列的對(duì)象交互。中介者使各對(duì)象不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。
中介者作為一種行為設(shè)計(jì)模式,它公開(kāi)一個(gè)統(tǒng)一的接口,系統(tǒng)的不同對(duì)象或組件可以通過(guò)該接口進(jìn)行通信。增加一個(gè)中介者對(duì)象后,所有的相關(guān)對(duì)象通過(guò)中介者對(duì)象來(lái)通信,而不是互相引用,所以當(dāng)一個(gè)對(duì)象發(fā)生改變時(shí),只需要通知中介者對(duì)象即可。
二、中介者模式的結(jié)構(gòu)

Mediator:中介者接口。在里面定義各個(gè)同事之間交互需要的方法,可以是公共的通訊方法,比如changed方法,大家都用,也可以是小范圍的交互方法。
ConcreteMediator:具體中介者實(shí)現(xiàn)對(duì)象。它需要了解并維護(hù)各個(gè)同事對(duì)象,并負(fù)責(zé)具體的協(xié)調(diào)各同事對(duì)象的交互關(guān)系。
Colleague:同事類(lèi)的定義,通常實(shí)現(xiàn)成為抽象類(lèi),主要負(fù)責(zé)約束同事對(duì)象的類(lèi)型,并實(shí)現(xiàn)一些具體同事類(lèi)之間的公共功能,比如:每個(gè)具體同事類(lèi)都應(yīng)該知道中介者對(duì)象,也就是具體同事類(lèi)都會(huì)持有中介者對(duì)象,就可以定義到這個(gè)類(lèi)里面。
ConcreteColleague:具體的同事類(lèi),實(shí)現(xiàn)自己的業(yè)務(wù),在需要與其它同事通訊的時(shí)候,就與持有的中介者通信,中介者會(huì)負(fù)責(zé)與其它的同事交互。
三、中介者模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn): 減少各個(gè)Colleague之間的耦合,使得可以獨(dú)立地改變和復(fù)用各個(gè)Colleague類(lèi)和Mediator
缺點(diǎn):中介者模式的缺點(diǎn)是顯而易見(jiàn)的,因?yàn)檫@個(gè)“中介“承擔(dān)了較多的責(zé)任,所以一旦這個(gè)中介對(duì)象出現(xiàn)了問(wèn)題,那么整個(gè)系統(tǒng)就會(huì)受到重大的影響。
四、中介者模式的使用場(chǎng)景
1. 一組定義良好的對(duì)象,現(xiàn)在要進(jìn)行復(fù)雜的通信。
2. 定制一個(gè)分布在多個(gè)類(lèi)中的行為,而又不想生成太多的子類(lèi)。
可以看出,中介對(duì)象主要是用來(lái)封裝行為的,行為的參與者就是那些對(duì)象,但是通過(guò)中介者,這些對(duì)象不用相互知道。
五、中介者模式與發(fā)布/訂閱模式的異同
1. 中介者模式與業(yè)務(wù)相關(guān),訂閱/發(fā)布模式與業(yè)務(wù)無(wú)關(guān)。
2. 兩個(gè)模式都有集中調(diào)度效果,對(duì)象之間不直接參與通信。
六、中介者模式的實(shí)現(xiàn)
安理會(huì)做中介
聯(lián)合國(guó)機(jī)構(gòu)類(lèi)--Mediator類(lèi)
//聯(lián)合國(guó)機(jī)構(gòu)
abstract class UnitedNations
{
//聲明
public abstract void Declare(string message, Country colleague);
}
國(guó)家類(lèi)--Colleague類(lèi)
//國(guó)家
abstract class Country
{
protected UnitedNations mediator;
public Country(UnitedNations mediator)
{
this.mediator = mediator;
}
}
美國(guó)類(lèi)--ConcreteColleague類(lèi)
//美國(guó)
class USA : Country
{
public USA(UnitedNations mediator) : base(mediator)
{
}
//聲明
public void Declare(string message)
{
mediator.Declare(message, this);
}
//獲取消息
public void GetMessage(string message)
{
Console.WriteLine("美國(guó)獲得對(duì)方消息:" + message);
}
}
伊拉克類(lèi)--ConcreteColleague類(lèi)
//伊拉克
class Iraq : Country
{
public Iraq(UnitedNations mediator) : base(mediator)
{
}
//聲明
public void Declare(string message)
{
mediator.Declare(message, this);
}
//獲取消息
public void GetMessage(string message)
{
Console.WriteLine("伊拉克獲得對(duì)方消息:" + message);
}
}
聯(lián)合國(guó)安理會(huì)--ConcreteMediator類(lèi)
//聯(lián)合國(guó)安全理事會(huì)
class UnitedNationsSecurity : UnitedNations
{
private USA colleague1;
private Iraq colleague2;
//美國(guó)
public USA Colleague1 { set { colleague1 = value; } }
//伊拉克
public Iraq Colleague2 { set { colleague2 = value; } }
public override void Declare(string message, Country colleague)
{
if (colleague == colleague1)
{
colleague2.GetMessage(message);
}
else
{
colleague1.GetMessage(message);
}
}
}
客戶端代碼
class Program
{
//客戶端代碼
static void Main(string[] args)
{
UnitedNationsSecurity UNSC = new UnitedNationsSecurity();
USA c1 = new USA(UNSC);
Iraq c2 = new Iraq(UNSC);
UNSC.Colleague1 = c1;
UNSC.Colleague2 = c2;
c1.Declare("不準(zhǔn)研發(fā)核武器,否則開(kāi)戰(zhàn)");
c2.Declare("沒(méi)研發(fā),開(kāi)戰(zhàn)就開(kāi)戰(zhàn)");
Console.Read();
}
}
結(jié)果
伊拉克獲得對(duì)方消息:不準(zhǔn)研發(fā)核武器,否則開(kāi)戰(zhàn)
美國(guó)獲得對(duì)方消息:沒(méi)研發(fā),開(kāi)戰(zhàn)就開(kāi)戰(zhàn)
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
SpringBoot用JdbcTemplates訪問(wèn)Mysql實(shí)例代碼
本篇文章主要介紹了SpringBoot用JdbcTemplates訪問(wèn)Mysql實(shí)例代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05
Java8 Stream Collectors收集器使用方法解析
這篇文章主要介紹了Java8 Stream Collectors收集器使用方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
Java讀取properties配置文件時(shí),出現(xiàn)中文亂碼的解決方法
下面小編就為大家?guī)?lái)一篇Java讀取properties配置文件時(shí),出現(xiàn)中文亂碼的解決方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11
SpringBoot深入分析webmvc和webflux的區(qū)別
這篇文章主要介紹了SpringBoot深入分析webmvc和webflux的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-02-02
MyBatis獲取插入記錄的自增長(zhǎng)字段值(ID)
本文分步驟給大家介紹了MyBatis獲取插入記錄的自增長(zhǎng)字段值的方法,在文中給大家提到了mybatis返回插入數(shù)據(jù)的自增長(zhǎng)id,需要的朋友可以參考下2017-11-11
Spring?boot?使用QQ郵箱進(jìn)行一個(gè)驗(yàn)證登入功能
這篇文章主要介紹了Spring?boot?使用QQ郵箱進(jìn)行一個(gè)驗(yàn)證登入,主要包括qq郵箱開(kāi)啟權(quán)限和創(chuàng)建發(fā)送驗(yàn)證碼的請(qǐng)求Controller,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-10-10

