生活随笔
收集整理的這篇文章主要介紹了
设计模式之中介模式
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一句話理解 :
我們交換 名片, 有事 告訴我 找誰,我處理
-
首先是我的名片
你拿著我的名片才能有事告訴我也就是說你要包含我的引用對吧
-
接下來是你們的名片
你們要把名片給我是不是太多不好拿 我是不是要有個文件夾
-
你啥時候把名片給我
你可以在創(chuàng)建的時候給我 (在構(gòu)造方法中)也可以創(chuàng)建完成后在給我(單獨在寫個方法)
這里我們在構(gòu)造方法中給
- 怎末告訴我找誰類
當(dāng)你想找我是不是要拿我名片打我電話
調(diào)用我的方法告訴我 找誰 干啥 (至少有兩個參數(shù) 吧)
這樣理解的話可以簡單的分析出中介者模式的結(jié)構(gòu)
- 抽象中介者(Mediator):定義好同事類對象到中介者對象的接口,用于各個同事類之間的通信。一般包括一個或幾個抽象的事件方法,并由子類去實現(xiàn)。
- 中介者實現(xiàn)類(Concrete Mediator):從抽象中介者繼承而來,實現(xiàn)抽象中介者中定義的事件方法。從一個同事類接收消息,然后通過消息影響其他同時類。
- 抽象同事類(Colleague)角色:定義同事類的接口,保存中介者對象,提供同事對象交互的抽象方法,實現(xiàn)所有相互影響的同事類的公共功能。(有的時候不需要這個角色)
- 同事類(Concrete Colleague):如果一個對象會影響其他的對象,同時也會被其他對象影響,那么這兩個對象稱為同事類。在類圖中,同事類只有一個,這其實是現(xiàn)實的省略,在實際應(yīng)用中,同事類一般由多個組成,他們之間相互影響,相互依賴。同事類越多,關(guān)系越復(fù)雜。并且,同事類也可以表現(xiàn)為繼承了同一個抽象類的一組實現(xiàn)組成。在中介者模式中,同事類之間必須通過中介者才能進行消息傳遞。
類圖
為什么要使用中介者模式
一般來說,同事類之間的關(guān)系是比較復(fù)雜的,多個同事類之間互相關(guān)聯(lián)時,他們之間的關(guān)系會呈現(xiàn)為復(fù)雜的網(wǎng)狀結(jié)構(gòu),這是一種過度耦合的架構(gòu),即不利于類的復(fù)用,也不穩(wěn)定。例如在下圖中,有六個同事類對象,假如對象1發(fā)生變化,那么將會有4個對象受到影響。如果對象2發(fā)生變化,那么將會有5個對象受到影響。也就是說,同事類之間直接關(guān)聯(lián)的設(shè)計是不好的。
如果引入中介者模式,那么同事類之間的關(guān)系將變?yōu)樾切徒Y(jié)構(gòu),從圖中可以看到,任何一個類的變動,只會影響的類本身,以及中介者,這樣就減小了系統(tǒng)的耦合。一個好的設(shè)計,必定不會把所有的對象關(guān)系處理邏輯封裝在本類中,而是使用一個專門的類來管理那些不屬于自己的行為。
是不是還有點不理解 看完下面這個例子在來討論
中介模式之(打麻將)
public interface Finance {void register(String name
, Players players
);void command(String name
,Integer number
);
}
import java.util.HashMap;
import java.util.Map;
public class Landlady implements Finance {private Map<String,Players> map
= new HashMap<String , Players>();@Overridepublic void register(String name
, Players players
) {map
.put(name
,players
);}@Overridepublic void command(String name
, Integer number
) {map
.get(name
).collectMoney(number
);}
}
public interface Players {void collectMoney(Integer number
); void pay(String name
,Integer number
);
}
public class East implements Players {private Finance finance
; private Integer moneyCount
; private String name
;public East(Finance finance
, Integer moneyCount
, String name
) {this.finance
= finance
;this.moneyCount
= moneyCount
;this.name
= name
;this.finance
.register(this.name
, this);}@Overridepublic void collectMoney(Integer number
) {this.moneyCount
+= number
;}@Overridepublic void pay(String name
, Integer number
) {if (this.moneyCount
<= number
) {System.out
.println(this.name
+ "無力支付費用換人");this.finance
.command(name
, this.moneyCount
);this.moneyCount
= 0;} else {this.moneyCount
-= number
;this.finance
.command(name
, number
);}}@Overridepublic String toString() {return "East{" +"finance=" + finance
+", moneyCount=" + moneyCount
+", name='" + name
+ '\'' +'}';}
}
public class West implements Players {private Finance finance
; private Integer moneyCount
; private String name
;public West(Finance finance
, Integer moneyCount
, String name
) {this.finance
= finance
;this.moneyCount
= moneyCount
;this.name
= name
;this.finance
.register(this.name
, this);}@Overridepublic void collectMoney(Integer number
) {this.moneyCount
+= number
;}@Overridepublic void pay(String name
, Integer number
) {if (this.moneyCount
<= number
) {System.out
.println(this.name
+ "無力支付費用換人");this.finance
.command(name
, this.moneyCount
);this.moneyCount
= 0;} else {this.moneyCount
-= number
;this.finance
.command(name
, number
);}}@Overridepublic String toString() {return "West{" +"finance=" + finance
+", moneyCount=" + moneyCount
+", name='" + name
+ '\'' +'}';}
}南北省略 寫法一樣
public class Client {public static void main(String[] args
) {Landlady landlady
= new Landlady();East east
= new East(landlady
, 50, "東");West west
= new West(landlady
, 50, "西");South south
= new South(landlady
, 50, "南");North north
= new North(landlady
, 50, "北");west
.pay("東", 10);System.out
.println(west
);System.out
.println(east
);north
.pay("東", 45);west
.pay("東", 45);south
.pay("東", 45);System.out
.println(west
);System.out
.println(east
);System.out
.println(north
);System.out
.println(south
);}
}
West{finance
=com.nwk.mediator.PlayPoker.Landlady@49476842, moneyCount
=40, name
='西'}
East{finance
=com.nwk.mediator.PlayPoker.Landlady@49476842, moneyCount
=60, name
='東'}
西無力支付費用換人
West{finance
=com.nwk.mediator.PlayPoker.Landlady@49476842, moneyCount
=0, name
='西'}
East{finance
=com.nwk.mediator.PlayPoker.Landlady@49476842, moneyCount
=190, name
='東'}
North{finance
=com.nwk.mediator.PlayPoker.Landlady@49476842, moneyCount
=5, name
='北'}
South{finance
=com.nwk.mediator.PlayPoker.Landlady@49476842, moneyCount
=5, name
='南'}
看到這 可能中介模式?jīng)]學(xué)會 滿腦子都是打麻將了吧
醒醒吧 學(xué)習(xí)了
現(xiàn)在再說說 為什么要使用中介者模式
1. 當(dāng)增加玩家或者減少玩家的時候不用去在原來的類里添加與之對應(yīng)的方法
2. 當(dāng)需要給錢時只需要把錢給中介(老板娘) 老板娘負(fù)責(zé)進行給錢的操作
3. 但是會增加中介類的負(fù)擔(dān) 當(dāng)中介類出問題時就會導(dǎo)致癱瘓(老板娘只收錢不給錢 一會就打錢來了)
用打麻將說就是
1、減少給錢和找錢的時間 (可以多打兩把)
2、防止因為錢的事扯皮(方便換人)
用系統(tǒng)來說
1、降低了類的復(fù)雜度,將一對多轉(zhuǎn)化成了一對一。
2、各個類之間的解耦。
以下來自 菜鳥教程 https://www.runoob.com/design-pattern/mediator-pattern.html
意圖:用一個中介對象來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。
主要解決:對象與對象之間存在大量的關(guān)聯(lián)關(guān)系,這樣勢必會導(dǎo)致系統(tǒng)的結(jié)構(gòu)變得很復(fù)雜,同時若一個對象發(fā)生改變,我們也需要跟蹤與之相關(guān)聯(lián)的對象,同時做出相應(yīng)的處理。
何時使用:多個類相互耦合,形成了網(wǎng)狀結(jié)構(gòu)。
如何解決:將上述網(wǎng)狀結(jié)構(gòu)分離為星型結(jié)構(gòu)。
關(guān)鍵代碼:對象 Colleague 之間的通信封裝到一個類中單獨處理。
應(yīng)用實例: 1、中國加入 WTO 之前是各個國家相互貿(mào)易,結(jié)構(gòu)復(fù)雜,現(xiàn)在是各個國家通過 WTO 來互相貿(mào)易。 2、機場調(diào)度系統(tǒng)。 3、MVC 框架,其中C(控制器)就是 M(模型)和 V(視圖)的中介者。
優(yōu)點: 1、降低了類的復(fù)雜度,將一對多轉(zhuǎn)化成了一對一。 2、各個類之間的解耦。 3、符合迪米特原則。
缺點:中介者會龐大,變得復(fù)雜難以維護。
使用場景: 1、系統(tǒng)中對象之間存在比較復(fù)雜的引用關(guān)系,導(dǎo)致它們之間的依賴關(guān)系結(jié)構(gòu)混亂而且難以復(fù)用該對象。 2、想通過一個中間類來封裝多個類中的行為,而又不想生成太多的子類。
注意事項:不應(yīng)當(dāng)在職責(zé)混亂的時候使用。
總結(jié)
以上是生活随笔為你收集整理的设计模式之中介模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。