Go和Java實現中介者模式
下面通過一個同事之間相互通信的例子來說明中介者模式的使用。
1、中介者模式
中介者模式是用來降低多個對象和類之間的通信復雜性。這種模式提供了一個中介類,該類通常處理不同類之間的
通信,并支持松耦合,使代碼易于維護。中介者模式屬于行為型模式。
-
意圖:用一個中介對象來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用,從而使其耦合松
散,而且可以獨立地改變它們之間的交互。
-
主要解決:對象與對象之間存在大量的關聯關系,這樣勢必會導致系統的結構變得很復雜,同時若一個對象發
生改變,我們也需要跟蹤與之相關聯的對象,同時做出相應的處理。
-
何時使用:多個類相互耦合,形成了網狀結構。
-
如何解決:將上述網狀結構分離為星型結構。
-
關鍵代碼:對象 Colleague 之間的通信封裝到一個類中單獨處理。
-
應用實例:1、中國加入 WTO 之前是各個國家相互貿易,結構復雜,現在是各個國家通過 WTO 來互相貿易。
2、機場調度系統。 3、MVC 框架,其中C(控制器)就是 M(模型)和 V(視圖)的中介者。
-
優點:1、降低了類的復雜度,將一對多轉化成了一對一。 2、各個類之間的解耦。 3、符合迪米特原則。
-
缺點:中介者會龐大,變得復雜難以維護。
-
使用場景:1、系統中對象之間存在比較復雜的引用關系,導致它們之間的依賴關系結構混亂而且難以復用該
對象。 2、想通過一個中間類來封裝多個類中的行為,而又不想生成太多的子類。
-
注意事項:不應當在職責混亂的時候使用。
-
適用性:
一組對象以定義良好但是復雜的方式進行通信,產生的相互依賴關系結構混亂且難以理解。
一個對象引用其他很多對象并且直接與這些對象通信,導致難以復現該對象。
想定制一個分布在多個類中的行為,而又不想生成太多的子類。
2、Go實現中介者模式
package mediator// ========== Colleague同事類 ==========
type Colleague interface {Send(string)Notify(string)
}
package mediatorimport "fmt"// ========== ColleagueA同事類A ==========
type ColleagueA struct {Mediator
}func (colleagueA *ColleagueA) Send(message string) {colleagueA.Mediator.Send(message, colleagueA)
}func (colleagueA *ColleagueA) Notify(message string) {fmt.Println("同事A得到信息:" + message)
}
package mediatorimport "fmt"// ========== ColleagueB同事類B ==========
type ColleagueB struct {Mediator
}func (colleagueB *ColleagueB) Send(message string) {colleagueB.Mediator.Send(message, colleagueB)}func (colleagueB *ColleagueB) Notify(message string) {fmt.Println("同事B得到信息:" + message)}
package mediator// ========== Mediator中介者類 ==========
type Mediator interface {Send(string, Colleague)
}
package com.mediator;// ========== ConcreteMediator ==========
public class ConcreteMediator extends Mediator{private ColleagueA colleagueA;private ColleagueB colleagueB;public void setColleagueA(ColleagueA colleagueA) {this.colleagueA = colleagueA;}public void setColleagueB(ColleagueB colleagueB) {this.colleagueB = colleagueB;}@Overridepublic void send(String message, Colleague colleague) {if (colleague == colleagueA){colleagueB.notify(message);}else{colleagueA.notify(message);}}
}
package mainimport . "proj/mediator"func main() {concreteMediator := ConcreteMediator{}colleagueA := ColleagueA{Mediator: &concreteMediator}colleagueB := ColleagueB{Mediator: &concreteMediator}concreteMediator.SetColleagueA(colleagueA)concreteMediator.SetColleagueB(colleagueB)colleagueA.Send("吃過飯了沒?")colleagueB.Send("沒有呢,你打算請客嗎?")
}
# 程序輸出
同事A得到信息:吃過飯了沒?
同事A得到信息:沒有呢,你打算請客嗎?
3、Java實現中介者模式
package com.mediator;// ========== Colleague同事類 ==========
public abstract class Colleague {protected Mediator mediator;public Colleague(Mediator mediator){this.mediator = mediator;}public void send(String message){this.mediator.send(message,this);}public abstract void notify(String message);
}
package com.mediator;// ========== ColleagueA同事類A ==========
public class ColleagueA extends Colleague{public ColleagueA(Mediator mediator) {super(mediator);}@Overridepublic void notify(String message){System.out.println("同事A得到信息:"+message);}
}
package com.mediator;// ========== ColleagueB同事類B ==========
public class ColleagueB extends Colleague{public ColleagueB(Mediator mediator) {super(mediator);}@Overridepublic void notify(String message){System.out.println("同事B得到信息:"+message);}
}
package com.mediator;// ========== Mediator中介者類 ==========
public abstract class Mediator {public abstract void send(String message,Colleague colleague);
}
package com.mediator;// ========== ConcreteMediator ==========
public class ConcreteMediator extends Mediator{private ColleagueA colleagueA;private ColleagueB colleagueB;public void setColleagueA(ColleagueA colleagueA) {this.colleagueA = colleagueA;}public void setColleagueB(ColleagueB colleagueB) {this.colleagueB = colleagueB;}@Overridepublic void send(String message, Colleague colleague) {if (colleague == colleagueA){colleagueB.notify(message);}else{colleagueA.notify(message);}}
}
package com.mediator;public class Test {public static void main(String[] args) {ConcreteMediator concreteMediator = new ConcreteMediator();ColleagueA colleagueA = new ColleagueA(concreteMediator);ColleagueB colleagueB = new ColleagueB(concreteMediator);concreteMediator.setColleagueA(colleagueA);concreteMediator.setColleagueB(colleagueB);colleagueA.send("吃過飯了沒?");colleagueB.send("沒有呢,你打算請客嗎?");}
}
# 程序輸出
同事B得到信息:吃過飯了沒?
同事A得到信息:沒有呢,你打算請客嗎?