設計模式--中介者模式Mediator(行為型)
1 定義:
1.1 定義:Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.(用一箇中介物件封裝一系列的物件互動,中介者使各物件不需要顯示地相互作用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。)
1.2 通用類圖:
Mediator抽象中介者角色
定義統一的介面,用於各同事角色之間的通訊。
Concrete Mediator具體中介者角色
協調各同事角色實現協作行為,因此它必須依賴於各個同事角色。
Colleague同事角色
每一個同事角色都知道中介者角色,而且與其他的同事角色通訊的時候,一定要通過中介者角色協作。每個同事類的行為分為兩種:一種是同事本身的行為,比如改變物件本身的狀態,處理自己的行為等,這種方法叫做自發行為(Self-Method),與其他同事類或中介者沒有任何的依賴;第二種是必須依賴中介者才能完成的行為,叫做依賴方法(Dep-Method)。
1.3 通用程式碼:
public abstract class Mediator {
// 定義同事類
protected ConcreteColleague1 c1;
protected ConcreteColleague2 c2;
// 通過getter/setter方法吧同事類注入進來
public ConcreteColleague1 getC1() {
return c1;
}
public void setC1(ConcreteColleague1 c1) {
this.c1 = c1;
}
public ConcreteColleague2 getC2() {
return c2;
}
public void setC2(ConcreteColleague2 c2) {
this.c2 = c2;
}
// 中介者模式的業務邏輯
public abstract void doSomething1();
public abstract void doSomething2();
}
public class ConcreteMediator extends Mediator {
@Override
public void doSomething1() {
// 呼叫同事類的方法,只要是public方法都可以呼叫
super.c1.selfMethod1();
super.c2.selfMethod2();
}
public void doSomething2() {
super.c1.selfMethod1();
super.c2.selfMethod2();
}
}
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator _mediator) {
this.mediator = _mediator;
}
}
public class ConcreteColleague1 extends Colleague {
// 通過建構函式傳遞中介者
public ConcreteColleague1(Mediator _mediator) {
super(_mediator);
}
// 自有方法 self-method
public void selfMethod1() {
// 處理自己的業務邏輯
}
// 依賴方法 dep-method
public void depMethod1() {
// 處理自己的業務邏輯
// 自己不能處理的業務邏輯,委託給中介者處理
super.mediator.doSomething1();
}
}
public class ConcreteColleague2 extends Colleague {
// 通過建構函式傳遞中介者
public ConcreteColleague2(Mediator _mediator) {
super(_mediator);
}
// 自有方法 self-method
public void selfMethod2() {
// 處理自己的業務邏輯
}
// 依賴方法 dep-method
public void depMethod2() {
// 處理自己的業務邏輯
// 自己不能處理的業務邏輯,委託給中介者處理
super.mediator.doSomething2();
}
}
注意:
A 在Mediator抽象類中我們只定義了同事類的get/set注入,為什麼不使用抽象注入呢?這是因為同事類雖然有抽象,但是沒有每個同事類必須要完成的業務方法。當然如果每個同事類都有相同的方法,比如execute 、handler等,那當然注入抽象類,做到依賴倒置。
B 為什麼同事類要使用建構函式注入中介者,而中介者注入同事類只使用getter/setter方式呢?因為同事類必須有中介者,而中介者卻可以只有部分同事類。
2 優點
減少類間的依賴,把原有的一對多的依賴變成了一對一依賴,同事類只依賴中介者,減少了依賴,當然同時也降低了類間的耦合。
3 缺點
中介者會膨脹得很大,而且邏輯複雜,原本N個物件直接的相互依賴關係轉換為中介者和同事類的依賴關係,同事類越多,中介者的邏輯就越複雜。
4 應用場景
類之間的聯絡是必然的,並非有多個依賴時就要使用中介者模式。中介者模式只適用於多個物件間緊密耦合的情況,緊密耦合的標準是:在類圖中出現了蜘蛛網狀結構。在這種情況下一定要考慮使用中介者模式,這有利於把蜘蛛網梳理為星型結構,使原本複雜混亂的關係變得清晰簡單。
4.1 符合上述緊密耦合標準時使用;
4.2 N個物件之間產生了相互的依賴關係(N>2);
4.3 多個物件有依賴關係,但是依賴的行為沿不確定或者有發生改變的可能,在這種情況下一般建議採用中介者模式,降低變更引起的風險擴散;
4.4 產品開發。一個明顯的例子就是MVC框架,把中介者模式應用到產品中,可以提升產品的效能和擴充套件性,但是對於專案開發就未必,因為專案是以交付投產為目標,而產品則是以穩定、高效、擴充套件為宗旨。
生活中的使用情境:
A。機場排程中心;
B。MVC框架;
C。媒體閘道器;(如MSN通過伺服器轉發訊息,而飛鴿直接使用UDP廣播卻不是。)
D。各種中介服務;
5 注意事項
5.1 遵循緊密耦合的標準來用中介者模式;
5.2 中介者模式很少用到介面或抽象類,這與依賴倒置原則是衝突的:首先,既然是同事類而不是兄弟類(有相同的血緣),那就說明這些類之間是協作關係,完成不同的任務,處理不同的業務,所以不能在抽象類或介面中嚴格定義同事類必須具有的方法。因此,如果兩個物件不能提煉出共性,就不要刻意去追求兩者的抽象,抽象只要定義出模式需要的角色即可。
其次,在一個專案中使用中介者模式可能被多個模組採用,每個中介者所圍繞的同事類各不相同,抽象出一個具有共性的中介者也不太可能。
6 擴充套件
無
7 範例
(進銷存案例,這三者間已形成了網狀關係)
加入了一箇中介者作為三個模組的交流核心,每個模組之間不再相互交流,要交流就通過中介者進行。每個模組只負責自己的業務邏輯,不屬於自己的則丟給中介者來處理,簡化了各模組之間的耦合關係,類圖如下:
/**
* @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
* all.
*/
public abstract class AbstractMediator {
protected Purchase purchase;
protected Sale sale;
protected Stock stock;
// 建構函式
public AbstractMediator() {
purchase = new Purchase(this);
sale = new Sale(this);
stock = new Stock(this);
}
// 中介者最重要的方法,叫做事件方法,處理多個物件之間的關係
public abstract void execute(String str, Object... objects);
}
public class Mediator extends AbstractMediator {
// 中介者最重要的方法
public void execute(String str, Object... objects) {
if (str.equals("purchase.buy")) { // 採購電腦
this.buyComputer((Integer) objects[0]);
} else if (str.equals("sale.sell")) { // 銷售電腦
this.sellComputer((Integer) objects[0]);
} else if (str.equals("sale.offsell")) { // 折價銷售
this.offSell();
} else if (str.equals("stock.clear")) { // 清倉處理
this.clearStock();
}
}
// 採購電腦
private void buyComputer(int number) {
int saleStatus = super.sale.getSaleStatus();
if (saleStatus > 80) { // 銷售情況良好
System.out.println("採購IBM電腦:" + number + "臺");
super.stock.increase(number);
} else { // 銷售情況不好
int buyNumber = number / 2; // 折半採購
System.out.println("採購IBM電腦:" + buyNumber + "臺");
}
}
// 銷售電腦
private void sellComputer(int number) {
if (super.stock.getStockNumber() < number) { // 庫存數量不夠銷售
super.purchase.buyIBMcomputer(number);
}
super.stock.decrease(number);
}
// 折價銷售電腦
private void offSell() {
System.out.println("折價銷售IBM電腦" + stock.getStockNumber() + "臺");
}
// 清倉處理
private void clearStock() {
// 要求清倉銷售
super.sale.offSale();
// 要求採購人員不要採購
super.purchase.refuseBuyIBM();
}
}
中介者Mediator定義了多個private方法,其目的是處理各個物件之間的依賴關係,就是說把原有一個物件要依賴的多個物件的情況移動到中介者的private方法中實現。
但在實際專案中,一般的做法是中介者按照職責進行劃分,每個中介者處理一個或多個類似的關聯請求。
public abstract class AbstractColleague {
protected AbstractMediator mediator;
public AbstractColleague(AbstractMediator _mediator) {
this.mediator = _mediator;
}
}
public class Purchase extends AbstractColleague {
public Purchase(AbstractMediator _mediator) {
super(_mediator);
}
// 採購IBM型號的電腦
public void buyIBMcomputer(int number) {
super.mediator.execute("purchase.buy", number);
}
// 不在採購IBM電腦
public void refuseBuyIBM() {
System.out.println("不再採購IBM電腦");
}
}
public class Stock extends AbstractColleague {
public Stock(AbstractMediator _mediator) {
super(_mediator);
}
// 剛開始有100臺電腦
private static int COMPUTER_NUMBER = 100;
// 庫存增加
public void increase(int number) {
COMPUTER_NUMBER = COMPUTER_NUMBER + number;
System.out.println("庫存數量為:" + COMPUTER_NUMBER);
}
// 庫存降低
public void decrease(int number) {
COMPUTER_NUMBER = COMPUTER_NUMBER - number;
System.out.println("庫存數量為:" + COMPUTER_NUMBER);
}
// 獲得庫存數量
public int getStockNumber() {
return COMPUTER_NUMBER;
}
// 存貨壓力大了,就要通知採購人員不要採購,銷售人員要儘快銷售
public void clearStock() {
System.out.println("清理存貨數量為:" + COMPUTER_NUMBER);
super.mediator.execute("stock.clear");
}
}
public class Sale extends AbstractColleague {
public Sale(AbstractMediator _mediator) {
super(_mediator);
}
// 銷售IBM型號的電腦
public void sellIBMComputer(int number) {
super.mediator.execute("sale.sell", number);
System.out.println("銷售IBM電腦" + number + "臺");
}
// 反饋銷售情況,0——100之間變化,0代表根本就沒人賣,100代表非常暢銷,出1一個賣一個
public int getSaleStatus() {
Random rand = new Random(System.currentTimeMillis());
int saleStatus = rand.nextInt(100);
System.out.println("IBM電腦的銷售情況為:" + saleStatus);
return saleStatus;
}
// 折價處理
public void offSale() {
super.mediator.execute("sale.offsell");
}
}
public class Client {
public static void main(String[] args) {
AbstractMediator mediator = new Mediator();
// 採購人員採購電腦
System.out.println("------採購人員採購電腦--------");
Purchase purchase = new Purchase(mediator);
purchase.buyIBMcomputer(100);
// 銷售人員銷售電腦
System.out.println("\n------銷售人員銷售電腦--------");
Sale sale = new Sale(mediator);
sale.sellIBMComputer(1);
// 庫房管理人員管理庫存
System.out.println("\n------庫房管理人員清庫處理--------");
Stock stock = new Stock(mediator);
stock.clearStock();
}
}
在場景類中增加了一箇中介者,然後分別傳遞到三個同事類中,三個類都具有相同的特性:只負責處理自己的活動(行為),與自己無關的活動就丟給中介者處理。
轉自:http://blog.csdn.net/yuanlong_zheng/article/details/7574441
相關文章
- 設計模式之中介者模式(行為型)設計模式
- Rust語言之GoF設計模式:中介者Mediator模式RustGo設計模式
- 設計模式-行為型模式-中介者模式設計模式
- Objective-C設計模式——中介者Mediator(物件去耦)Object設計模式物件
- 行為型模式:中介者模式模式
- 設計模式之中介者模式設計模式
- 行為型設計模式 - 觀察者模式詳解設計模式
- 設計模式系列之中介者模式(Mediator Pattern)——協調多個物件之間的互動設計模式物件
- 極簡設計模式-中介者模式設計模式
- 設計模式實戰 - 中介者模式設計模式
- 行為型設計模式設計模式
- 設計模式(十七)中介者設計模式
- 設計模式之中介者設計模式
- 行為型設計模式---模板方法觀察者模式責任鏈模式設計模式
- Java學設計模式之中介者模式Java設計模式
- 設計模式學習(十八)中介者模式設計模式
- C#設計模式(16)——中介者模式C#設計模式
- Android原始碼設計模式-中介者模式Android原始碼設計模式
- C#設計模式之中介者模式C#設計模式
- Mediator(中介者)模式在iOS開發當中的使用模式iOS
- (Java)設計模式:行為型Java設計模式
- 設計模式----中介模式設計模式
- 設計模式-中介模式設計模式
- 聊一聊設計模式(四)-- 行為型設計模式設計模式
- 18.java設計模式之中介者模式Java設計模式
- 設計模式(十九)——中介者模式(智慧家庭案例)設計模式
- 設計模式 | 中介者模式及典型應用設計模式
- 折騰Java設計模式之中介者模式Java設計模式
- 行為型設計模式 - 狀態模式詳解設計模式
- 軟體設計模式系列之十九——中介者模式設計模式
- 行為型設計模式 - 備忘錄模式詳解設計模式
- 行為型設計模式 - 責任鏈模式詳解設計模式
- 物件導向-設計模式-行為型物件設計模式
- 大話 PHP 設計模式--行為型PHP設計模式
- Java進階篇設計模式之十 ---- 訪問者模式和中介者模式Java設計模式
- 行為型:觀察者模式模式
- 《JavaScript設計模式與開發實踐》模式篇(11)—— 中介者模式JavaScript設計模式
- 中介者設計模式——業務實踐設計模式
- 軟體設計模式學習(二十一)中介者模式設計模式