.Net行為型設(shè)計(jì)模式之中介者模式(Mediator)
一、動(dòng)機(jī)(Motivate)
為什么要使用中介者模式呢?如果不使用中介者模式的話,各個(gè)同事對(duì)象將會(huì)相互進(jìn)行引用,如果每個(gè)對(duì)象都與多個(gè)對(duì)象進(jìn)行交互時(shí),將會(huì)形成如下圖所示的網(wǎng)狀結(jié)構(gòu)。
從上圖可以發(fā)現(xiàn),如果不使用中介者模式的話,每個(gè)對(duì)象之間過(guò)度耦合,這樣的既不利于類(lèi)的復(fù)用也不利于擴(kuò)展。如果引入了中介者模式,那么對(duì)象之間的關(guān)系將變成星型結(jié)構(gòu),采用中介者模式之后會(huì)形成如下圖所示的結(jié)構(gòu):
從上圖可以發(fā)現(xiàn),使用中介者模式之后,任何一個(gè)類(lèi)的變化,只會(huì)影響中介者和類(lèi)本身,不像之前的設(shè)計(jì),任何一個(gè)類(lèi)的變化都會(huì)引起其關(guān)聯(lián)所有類(lèi)的變化。這樣的設(shè)計(jì)大大減少了系統(tǒng)的耦合度。
在軟件構(gòu)建過(guò)程中,經(jīng)常會(huì)出現(xiàn)多個(gè)對(duì)象互相關(guān)聯(lián)交互的情況,對(duì)象之間常常會(huì)維持一種復(fù)雜的引用關(guān)系,如果遇到一些需求的更改,這種直接的引用關(guān)系將面臨不斷地變化。
在這種情況下,我們可使用一個(gè)“中介對(duì)象”來(lái)管理對(duì)象間的關(guān)聯(lián)關(guān)系,避免相互交互的對(duì)象之間的緊耦合引用關(guān)系,從而更好地抵御變化。
二、意圖(Intent)
定義了一個(gè)中介對(duì)象來(lái)封裝一系列對(duì)象之間的交互關(guān)系。中介者使各個(gè)對(duì)象之間不需要顯式地相互引用,從而使耦合性降低,而且可以獨(dú)立地改變它們之間的交互行為。 ——《設(shè)計(jì)模式》GoF
三、結(jié)構(gòu)圖(Structure)
四、模式的組成
可以看出,在中介者模式的結(jié)構(gòu)圖有以下角色:
(1)、抽象中介者角色(Mediator):在里面定義各個(gè)同事之間交互需要的方法,可以是公共的通信方法,也可以是小范圍的交互方法。
(2)、具體中介者角色(ConcreteMediator):它需要了解并維護(hù)各個(gè)同事對(duì)象,并負(fù)責(zé)具體的協(xié)調(diào)各同事對(duì)象的交互關(guān)系。
(3)、抽象同事類(lèi)(Colleague):通常為抽象類(lèi),主要約束同事對(duì)象的類(lèi)型,并實(shí)現(xiàn)一些具體同事類(lèi)之間的公共功能,比如,每個(gè)具體同事類(lèi)都應(yīng)該知道中介者對(duì)象,也就是具體同事類(lèi)都會(huì)持有中介者對(duì)象,都可以到這個(gè)類(lèi)里面。
(4)、具體同事類(lèi)(ConcreteColleague):實(shí)現(xiàn)自己的業(yè)務(wù),需要與其他同事通信時(shí)候,就與持有的中介者通信,中介者會(huì)負(fù)責(zé)與其他同事類(lèi)交互。
五、中介者模式的代碼實(shí)現(xiàn)
中介者模式在現(xiàn)實(shí)生活中也有類(lèi)似的例子,不論是QQ群或者是微信群,或者手提電話,它們都是充當(dāng)一個(gè)中間平臺(tái),QQ用戶(hù)可以登錄這個(gè)中間平臺(tái)與其他QQ用戶(hù)進(jìn)行交流,如果沒(méi)有這些中間平臺(tái),我們?nèi)绻肱c朋友進(jìn)行聊天的話,可能就需要當(dāng)面才可以了。比如:在公司管理過(guò)程中,就會(huì)涉及到各個(gè)部門(mén)之間的協(xié)調(diào)和合作,如何各個(gè)部門(mén)直接來(lái)溝通,看著好像直接高效,其實(shí)不然。各個(gè)部門(mén)之間為了完成一個(gè)工作,溝通協(xié)調(diào)就需要一個(gè)人來(lái)做這個(gè)工作,誰(shuí)呢?總經(jīng)理,我們這里就把總經(jīng)理定義為成總的管理者,各個(gè)部門(mén)需要向他匯報(bào)和發(fā)起工作請(qǐng)求。
static void Main(String[] args) { President mediator = new President(); Market market = new Market(mediator); Development development = new Development(mediator); Financial financial = new Financial(mediator); mediator.SetFinancial(financial); mediator.SetDevelopment(development); mediator.SetMarket(market); market.Process(); market.Apply(); } //抽象中介者角色 public interface Mediator { void Command(Department department); } //總經(jīng)理--相當(dāng)于具體中介者角色 public sealed class President : Mediator { //總經(jīng)理有各個(gè)部門(mén)的管理權(quán)限 private Financial _financial; private Market _market; private Development _development; public void SetFinancial(Financial financial) { this._financial = financial; } public void SetDevelopment(Development development) { this._development = development; } public void SetMarket(Market market) { this._market = market; } public void Command(Department department) { if (department.GetType() == typeof(Market)) { _financial.Process(); } } } //同事類(lèi)的接口 public abstract class Department { //持有中介者(總經(jīng)理)的引用 private Mediator mediator; protected Department(Mediator mediator) { this.mediator = mediator; } public Mediator GetMediator { get { return mediator; } private set { this.mediator = value; } } //做本部門(mén)的事情 public abstract void Process(); //向總經(jīng)理發(fā)出申請(qǐng) public abstract void Apply(); } //開(kāi)發(fā)部門(mén) public sealed class Development : Department { public Development(Mediator m) : base(m) { } public override void Process() { Console.WriteLine("我們是開(kāi)發(fā)部門(mén),要進(jìn)行項(xiàng)目開(kāi)發(fā),沒(méi)錢(qián)了,需要資金支持!"); } public override void Apply() { Console.WriteLine("專(zhuān)心科研,開(kāi)發(fā)項(xiàng)目!"); } } //財(cái)務(wù)部門(mén) public sealed class Financial : Department { public Financial(Mediator m) : base(m) { } public override void Process() { Console.WriteLine("匯報(bào)工作!沒(méi)錢(qián)了,錢(qián)太多了!怎么花?"); } public override void Apply() { Console.WriteLine("數(shù)錢(qián)!"); } } //市場(chǎng)部門(mén) public sealed class Market : Department { public Market(Mediator mediator) : base(mediator) { } public override void Process() { Console.WriteLine("匯報(bào)工作!項(xiàng)目承接的進(jìn)度,需要資金支持!"); GetMediator.Command(this); } public override void Apply() { Console.WriteLine("跑去接項(xiàng)目!"); } }
六、中介者模式的實(shí)現(xiàn)要點(diǎn):
將多個(gè)對(duì)象間復(fù)雜的關(guān)聯(lián)關(guān)系解耦,Mediator模式將多個(gè)對(duì)象間的控制邏輯進(jìn)行集中管理,變“多個(gè)對(duì)象互相關(guān)聯(lián)”為“多個(gè)對(duì)象和一個(gè)中介者關(guān)聯(lián)”,簡(jiǎn)化了系統(tǒng)的維護(hù),抵御了可能的變化。隨著控制邏輯的復(fù)雜化,Mediator具體對(duì)象的實(shí)現(xiàn)可能相當(dāng)復(fù)雜。這時(shí)候可以對(duì)Mediator對(duì)象進(jìn)行分解處理。
- Facade模式是解耦系統(tǒng)外到系統(tǒng)內(nèi)(單向)的對(duì)相關(guān)聯(lián)關(guān)系
- Mediator模式是解耦系統(tǒng)內(nèi)各個(gè)對(duì)象之間(雙向)的關(guān)聯(lián)關(guān)系
1、中介者模式的優(yōu)點(diǎn)
(1)、松散耦合:中介者模式通過(guò)把多個(gè)同事對(duì)象之間的交互封裝到中介對(duì)象里面,從而使得對(duì)象之間松散耦合,基本上可以做到互不依賴(lài)。這樣一來(lái),同時(shí)對(duì)象就可以獨(dú)立的變化和復(fù)用,不再“牽一發(fā)動(dòng)全身”
(2)、集中控制交互:多個(gè)同事對(duì)象的交互,被封裝在中介者對(duì)象里面集中管理,使得這些交互行為發(fā)生變化的時(shí)候,只需要修改中介者就可以了。
(3)、多對(duì)多變?yōu)橐粚?duì)多:沒(méi)有中介者模式的時(shí)候,同事對(duì)象之間的關(guān)系通常是多對(duì)多,引入中介者對(duì)象后,中介者和同事對(duì)象的關(guān)系通常變?yōu)殡p向的一對(duì)多,這會(huì)讓對(duì)象的關(guān)系更容易理解和實(shí)現(xiàn)。
2、中介者模式的缺點(diǎn)
過(guò)多集中化:如果同事對(duì)象之間的交互非常多,而且比較復(fù)雜,當(dāng)這些復(fù)雜性全都集中到中介者的時(shí)候,會(huì)導(dǎo)致中介者對(duì)象變的十分復(fù)雜,而且難于維護(hù)和管理。
七、.NET 中介者模式的實(shí)現(xiàn)
根據(jù)我個(gè)人的理解,微軟的ASP.NET MVC開(kāi)發(fā)模式就是一個(gè)中介者模式的很好的實(shí)現(xiàn),其中C就是Controller,也就是中文所說(shuō)的控制器,控制器就是一個(gè)中介者,M和V和它打交道,具體的情況大家可以去查看相關(guān)資料,這方面的資料還是很多的。
到此這篇關(guān)于.Net行為型設(shè)計(jì)模式之中介者模式(Mediator)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- .Net行為型設(shè)計(jì)模式之備忘錄模式(Memento)
- .Net行為型設(shè)計(jì)模式之訪問(wèn)者模式(Visitor)
- .Net行為型設(shè)計(jì)模式之職責(zé)鏈模式(Chain of Responsibility)
- .Net行為型設(shè)計(jì)模式之策略模式(Stragety)
- .Net行為型設(shè)計(jì)模式之狀態(tài)模式(State)
- .Net行為型設(shè)計(jì)模式之觀察者模式(Observer)
- .Net行為型設(shè)計(jì)模式之迭代器模式(Iterator)
- .Net行為型設(shè)計(jì)模式之命令模式(Command)
- .Net行為型設(shè)計(jì)模式之模板方法模式(Template?Method)
- .Net行為型設(shè)計(jì)模式之解釋器模式(Interpreter)
相關(guān)文章
ASP.Net頁(yè)面生命周期與Page_Load方法的工作原理介紹
這篇文章介紹了ASP.Net頁(yè)面生命周期與Page_Load方法的工作原理,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05.Net結(jié)構(gòu)型設(shè)計(jì)模式之橋接模式(Bridge)
這篇文章介紹了.Net結(jié)構(gòu)型設(shè)計(jì)模式之橋接模式(Bridge),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05Linux Ubuntu系統(tǒng)上手動(dòng)安裝.NET Core SDK的方法
.NET Core是一個(gè)開(kāi)源通用的開(kāi)發(fā)框架,支持跨平臺(tái),即支持在Window,macOS,Linux等系統(tǒng)上的開(kāi)發(fā)和部署,并且可以在硬件設(shè)備,云服務(wù),和嵌入式/物聯(lián)網(wǎng)方案中進(jìn)行使用。下面這篇文章將給大家詳細(xì)介紹關(guān)于在Linux Ubuntu系統(tǒng)上手動(dòng)安裝.NET Core SDK的方法。2016-12-12發(fā)布WEB站點(diǎn)時(shí)出現(xiàn)Server Application Unavailable
發(fā)布WEB站點(diǎn)時(shí)出現(xiàn)Server Application Unavailable...2006-12-12.Net行為型設(shè)計(jì)模式之狀態(tài)模式(State)
這篇文章介紹了.Net行為型設(shè)計(jì)模式之狀態(tài)模式(State),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05