一、中介者模式的定義與特點
中介者(Mediator)模式的定義:定義一個中介對象來封裝一系列對象之間的交互,使原有對象之間的耦合松散,且可以獨立地改變它們之間的交互。中介者模式又叫調停模式,它是迪米特法則的典型應用。
二、中介者模式優缺點
中介者模式是一種對象行為型模式,其主要優點如下:
- 降低了對象之間的耦合性,使得對象易於獨立地被復用。
- 將對象間的一對多關聯轉變為一對一的關聯,提高系統的靈活性,使得系統易於維護和擴展。
其主要缺點是:
- 當同事類太多時,中介者的職責將很大,它會變得復雜而龐大,以至於系統難以維護。
三、中介者模式的實現
中介者模式實現的關鍵是找出“中介者”,下面對它的結構和實現進行分析。
中介者模式包含以下主要角色:
- 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事對象注冊與轉發同事對象信息的抽象方法。
- 具體中介者(ConcreteMediator)角色:實現中介者接口,定義一個 List 來管理同事對象,協調各個同事角色之間的交互關系,因此它依賴於同事角色。
- 抽象同事類(Colleague)角色:定義同事類的接口,保存中介者對象,提供同事對象交互的抽象方法,實現所有相互影響的同事類的公共功能。
- 具體同事類(Concrete Colleague)角色:是抽象同事類的實現者,當需要與其他同事對象交互時,由中介者對象負責后續的交互。
中介者模式的結構圖如圖所示:
代碼如圖所示:
public class MediatorPattern { public static void main(String[] args) { Mediator md=new ConcreteMediator(); Colleague c1,c2; c1=new ConcreteColleague1(); c2=new ConcreteColleague2(); md.register(c1); md.register(c2); c1.send(); System.out.println("-------------"); c2.send(); } } //抽象中介者 abstract class Mediator { public abstract void register(Colleague colleague); public abstract void relay(Colleague cl); //轉發 } //具體中介者 class ConcreteMediator extends Mediator { private List<Colleague> colleagues=new ArrayList<Colleague>(); public void register(Colleague colleague) { if(!colleagues.contains(colleague)) { colleagues.add(colleague); colleague.setMedium(this); } } public void relay(Colleague cl) { for(Colleague ob:colleagues) { if(!ob.equals(cl)) { ((Colleague)ob).receive(); } } } } //抽象同事類 abstract class Colleague { protected Mediator mediator; public void setMedium(Mediator mediator) { this.mediator=mediator; } public abstract void receive(); public abstract void send(); } //具體同事類 class ConcreteColleague1 extends Colleague { public void receive() { System.out.println("具體同事類1收到請求。"); } public void send() { System.out.println("具體同事類1發出請求。"); mediator.relay(this); //請中介者轉發 } } //具體同事類 class ConcreteColleague2 extends Colleague { public void receive() { System.out.println("具體同事類2收到請求。"); } public void send() { System.out.println("具體同事類2發出請求。"); mediator.relay(this); //請中介者轉發 } }
執行結果如下:
具體同事類1發出請求。 具體同事類2收到請求。 ------------- 具體同事類2發出請求。 具體同事類1收到請求。
四、中介者模式的應用場景
前面分析了中介者模式的結構與特點,下面分析其以下應用場景。
- 當對象之間存在復雜的網狀結構關系而導致依賴關系混亂且難以復用時。
- 當想創建一個運行於多個類之間的對象,又不想生成新的子類時。
五、中介者模式的擴展
在實際開發中,通常采用以下兩種方法來簡化中介者模式,使開發變得更簡單。
- 不定義中介者接口,把具體中介者對象實現成為單例。
- 同事對象不持有中介者,而是在需要的時候直接獲取中介者對象並調用。
簡化中介者模式的結構圖如圖所示:
代碼實現如下:
public class SimpleMediatorPattern { public static void main(String[] args) { SimpleColleague c1,c2; c1=new SimpleConcreteColleague1(); c2=new SimpleConcreteColleague2(); c1.send(); System.out.println("-----------------"); c2.send(); } } //簡單單例中介者 class SimpleMediator { private static SimpleMediator smd=new SimpleMediator(); private List<SimpleColleague> colleagues=new ArrayList<SimpleColleague>(); private SimpleMediator(){} public static SimpleMediator getMedium() { return(smd); } public void register(SimpleColleague colleague) { if(!colleagues.contains(colleague)) { colleagues.add(colleague); } } public void relay(SimpleColleague scl) { for(SimpleColleague ob:colleagues) { if(!ob.equals(scl)) { ((SimpleColleague)ob).receive(); } } } } //抽象同事類 interface SimpleColleague { void receive(); void send(); } //具體同事類 class SimpleConcreteColleague1 implements SimpleColleague { SimpleConcreteColleague1(){ SimpleMediator smd=SimpleMediator.getMedium(); smd.register(this); } public void receive() { System.out.println("具體同事類1:收到請求。"); } public void send() { SimpleMediator smd=SimpleMediator.getMedium(); System.out.println("具體同事類1:發出請求..."); smd.relay(this); //請中介者轉發 } } //具體同事類 class SimpleConcreteColleague2 implements SimpleColleague { SimpleConcreteColleague2(){ SimpleMediator smd=SimpleMediator.getMedium(); smd.register(this); } public void receive() { System.out.println("具體同事類2:收到請求。"); } public void send() { SimpleMediator smd=SimpleMediator.getMedium(); System.out.println("具體同事類2:發出請求..."); smd.relay(this); //請中介者轉發 } }
運行結果如下:
具體同事類1:發出請求... 具體同事類2:收到請求。 ----------------- 具體同事類2:發出請求... 具體同事類1:收到請求。