再說設計模式-中介者模式(調停者模式)

定義

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.
用一箇中介對象封裝一系列的對象交互,中介者使各對象不需要顯示地相互作用,從而使用其耦合鬆散,而且可以獨立地改變它們之間的交互。

中介者模式能用類圖如下所示:


從類圖中看,中介者模式由以下幾部分組成:

  • Mediator抽象中介者角色
    抽象中介者角色定義統一的接口,用於各同事角色之間的通信。
  • Concrete Mediator具體中介者角色
    具體中介者角色通過協調各同事實現協作行爲,因此它必須依賴於各個同事角色。
  • Colleague同事角色
    每一個同事角色都知道中介者角色,而且與其他的同事角色通信的時候,一定要通過中介者角色協作。每個同事的行爲分爲兩種:
    第一種是同事本身的行爲,比如改變對象本身的狀態,處理自己的行爲等,這種方法叫做自發行爲(Self-Method),與其他的同事類或中介者沒有任何的依賴;
    第二種是必須依賴中介者才能完成的行爲,叫做依賴方法(Dep-Method)。

通用抽象中介者類:

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 setC1(ConcreteColleague2 c2) {
    this.c2 = c2;
  }
  // 中介者模式的業務邏輯
  public abstract void doSomething1();
  public abstract void doSomething2();
}

在Mediator抽象類中,我們只定義了同事類的注入,爲什麼使用同事實現類注入而不使用抽象類注入呢? 那是因爲同事類雖然有抽象,但是沒有每個同事類必須要完成的業務方法,當然如果每個同事類都有相同的方法,如execute,handler等,那當然注入抽象類,做到依賴倒置

具體的中介者一般只有一個,即通用中介者,其源代碼如下:

public class ConcreteMediator extends Mediator {
  @Override
  public void doSomething1() {
    // 調用同事類的方法,只要是public方法都可以調用
    supper.c1.selfMethod1();
    supper.c2.selfMethod2();
  }

  @Override
  public void doSomething2() {
    // 調用同事類的方法,只要是public方法都可以調用
    supper.c1.selfMethod1();
    supper.c2.selfMethod2();
  }
}

中介者所具有的方法doSomething1和doSomething2都是比較複雜的業務邏輯,爲同事類服務,其實現是依賴各個同事類來完成的。

抽象同事類:

public abstract class Colleagua {
  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();
  }
}

同事類ConcreteColleague2也類似;

特點

  • 優點 - 減少了類間的依賴,把原來的一對多的依賴變成了一對一的依賴,同事類保依賴中介者,減少了依賴,當然同時也降低了類間的耦合。
  • 缺點 - 中介者會膨脹得很大,而且邏輯複雜,原本N個對象直接的相互依賴關係轉換爲中介者和同事類的依賴關係,同事類越多,中介者的邏輯就越複雜。

PS 中介者模式的使用需要量力而行,中介者模式適用於多個對象之間緊密耦合的情況,緊密耦合的標準是:在類圖中出現了蜘蛛網狀結構。在這種情況下一定要考慮使用中介者模式,這有利於把蜘蛛網梳理爲星形結構,使原本複雜混亂的關係變得清晰簡單。

實際應用場景

大家都應該熟悉的Structs,MVC框架,其中的C(Controller)就是一箇中介者,叫做前端控制器(Front Controller),它的使用就是把M(Model,業務邏輯)V(View,視圖)隔離開,協調M和V協同工作,把M運行的結果和V代表的視圖融合成一個前端可以展示的頁面,減少M和V的依賴關係。

最佳實踐

  • N個對象之間產生了相互依賴的關係(N > 2)
  • 多個對象有依賴關係,但是依賴的行爲尚不確定或者有發生改變的可能,在這種情況下一般建議採用中介者模式,降低變更引起的風險擴散。
  • 產品開發。一個明顯的例子就是MVC框架,把中介者模式應用到產品中,可以提升產品的性能和擴展性,但是對於項目開發就未必,因爲項目是以交付投產爲目標,而產品則是以穩定、高效、擴展爲宗旨。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章