設計模式之中介者模式(Mediator Pattern)
阿新 • • 發佈:2018-12-18
-
中介者模式定義
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
public abstract class Mediator { protected ConcreteColleague1 c1; protected ConcreteColleague2 c2; 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 doSth1(); public abstract void doSth2(); }
抽象同事類Colleague
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator _mediator) {
this.mediator = _mediator;
}
}
具體中介者
public class ConcreteMediator extends Mediator{
@Override
public void doSth1() {
super.c1.selfMethod1();
super.c2.selfMethod2();
}
@Override
public void doSth2() {
super.c1.selfMethod1();
super.c2.selfMethod2();
}
}
具體同事類
public class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator _mediator) {
super(_mediator);
}
public void selfMethod1() {
//TODO
}
public void depMethod1() {
super.mediator.doSth1();
}
}
public class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator _mediator) {
super(_mediator);
}
public void selfMethod2() {
// TODO
}
public void depMethod2() {
super.mediator.doSth2();
}
}
- 中介者模式例項類圖
相比有很多男生都喜歡金庸的武俠小說吧,筆者也不例外。江湖中門派眾多,總會有一些小嘍囉偷學少林絕學去做一些見不得人的勾當。前段時間武當派和峨眉派的的弟子被大力金剛指所殺,大力金剛指是少林派的絕學,自古有天下武功出少林的沒說,大家自然也不敢輕舉妄動。這個時候大家推舉出了德高望重的武林盟主,作為江湖的中間人,一旦有什麼不和諧的地方,由武林盟主出面進行溝通,其實這個例子就符合中介者模式。
- 中介者模式例項程式碼
抽象中介者類
public abstract class WulinAlliance {
abstract void notice(String message, United united);
}
抽象同事類
public abstract class United {
protected WulinAlliance wulinAlliance;
public United(WulinAlliance wulinAlliance) {
this.wulinAlliance = wulinAlliance;
}
}
具體同事類
public class Wudang extends United {
public Wudang(WulinAlliance wulinAlliance) {
super(wulinAlliance);
}
public void sendAlliance(String message) {
wulinAlliance.notice(message, this);
}
public void getNotice(String message) {
System.out.println("武當收到訊息:" + message);
}
}
public class Shaolin extends United {
public Shaolin(WulinAlliance wulinAlliance) {
super(wulinAlliance);
}
public void sendAlliance(String message) {
wulinAlliance.notice(message, Shaolin.this);
}
public void getNotice(String message) {
System.out.println("少林收到訊息:" + message);
}
}
public class Emei extends United {
public Emei(WulinAlliance wulinAlliance) {
super(wulinAlliance);
}
public void sendAlliance(String message) {
wulinAlliance.notice(message, Emei.this);
}
public void getNotice(String message) {
System.out.println("峨眉收到訊息:" + message);
}
}
具體中介者類
public class Champions extends WulinAlliance {
private Wudang wudang;
private Shaolin shaolin;
private Emei emei;
public void setWudang(Wudang wudang) {
this.wudang = wudang;
}
public void setEmei(Emei emei) {
this.emei = emei;
}
public void setShaolin(Shaolin shaolin) {
this.shaolin = shaolin;
}
@Override
public void notice(String message, United united) {
if (united == wudang) {
shaolin.getNotice(message);
} else if (united == emei) {
shaolin.getNotice(message);
} else if (united == shaolin) {
wudang.getNotice(message);
emei.getNotice(message);
}
}
}
客戶端呼叫
public class Client {
public static void main(String[] args) {
Champions champions = new Champions();
Wudang wudang = new Wudang(champions);
Shaolin shaolin = new Shaolin(champions);
Emei emei = new Emei(champions);
champions.setWudang(wudang);
champions.setShaolin(shaolin);
champions.setEmei(emei);
wudang.sendAlliance("武當弟子被少林大力金剛指所殺");
emei.sendAlliance("峨眉弟子被少林大力金剛指所殺");
shaolin.sendAlliance("少林弟子絕不會做出這種事情");
}
}
輸出結果:
少林收到訊息:武當弟子被少林大力金剛指所殺
少林收到訊息:峨眉弟子被少林大力金剛指所殺
武當收到訊息:少林弟子絕不會做出這種事情
峨眉收到訊息:少林弟子絕不會做出這種事情
- 中介者模式的優點
- 符合迪米特原則,將原有的一對多的依賴變成了一對一的依賴,降低類間的耦合。
- 使用中介者模式可以將物件的行為和協作進行抽象,能夠比較靈活的處理物件間的相互作用。
- 中介者模式的適用場景
- 系統中物件之間存在比較複雜的引用關係,導致他們之間的依賴關係結構混亂而且難以複用該物件。
- 想通過一箇中間類來封裝多個類中的行為,而又不想生成太多的子類。
參考書籍:設計模式之禪
例項程式碼放在這裡。