1. 中介者模式(Mediator pattern)定義
使用中介者模式來集中相關對象之間複雜的溝通和控制方式,使得這些對象不必相互明顯引用。從而使它們可以較鬆散地耦合。當這些對象中的某些對象之間的相互作用發生改變時,不會立即影響到其他的一些對象之間的相互作用。從而保證這些相互作用可以彼此獨立地變化。
2. 中介者的作用
如下圖所示,此圖中有6個對象,這些對象既會影響別的對象,又會被別的對象所影響,因此常常叫做同事(Colleague)對象。這些同事對象通過彼此的相互作用形成系統的行爲。從圖中可以看出,當對象1改變時,除了對象3之外其他所有對象都有可能受到影響;當對象2改變時,所有對象都有可能受到影響。這就是過度耦合的系統。
通過引入中介者(Mediator),那麼同事類之間的關係將變成星型結構。如下圖所示,在這個星型結構中,同事對象不再通過直接的聯繫與另一個對象發生相互作用;相反的,它通過中介者對象與另一個對象發生相互作用。中介者對象的存在保證了對象結構上的穩定,也就是說,系統的結構不會因爲新對象的引入造成大量的修改工作。
3. 中介者模式的結構
類圖:
角色說明:
-
抽象中介者角色(AbstractMediator):定義出同事對象到中介者對象的接口,其中主要方法是一個(或多個)事件方法。
-
具體中介者角色(ConcreteMediator):實現抽象中介者中所聲明的事件方法。具體中介者直銷所有的具體同事類,並負責具體的協調各個同事對象的交互關係。
-
抽象同事類角色(AbstractColleague):定義出紅接着到同事對象的接口。同事對象只知道中介者,而不知道其餘的同事對象。
-
具體同事類角色(ConcreteColleague):所有的具體同事類均從抽象同事類繼承而來。實現自己的業務,在需要與其他同事通信的時候,就與持有的中介者通信,中介者會負責與其他的同時交互。
4. 代碼演示
抽象中介者:
public interface AbstractMediator {
//中介者通過此方法來改變同事B
public void aChangedB(String str);
//中介者通過此方法來改變同事A
public void bChangedA(String str);
}
抽象同事類:
public abstract class AbstractColleague {
//同事對象在改變的時候,通知中介者,並傳遞影響值
public abstract void setString(String str, AbstractMediator am);
//同事對象提供一個接口接收中介者傳遞的影響值
public abstract void changeString(String str);
}
具體同事類A:
public class ConcreteColleagueA extends AbstractColleague {
// 同事A的字符串屬性
private String strAttribute;
// 構造函數,構造字符串屬性
public ConcreteColleagueA(String str) {
this.strAttribute = str;
}
/**
* 被改變的函數
*/
@Override
public void changeString(String str) {
this.strAttribute = this.strAttribute + "這是同事B對我的影響:" + str;
}
/**
* 改變時,通知中介者改變其他同事
*/
@Override
public void setString(String str, AbstractMediator am) {
am.aChangedB(str);
}
public String getStrAttribute() {
return strAttribute;
}
}
具體同事類B:
public class ConcreteColleagueB extends AbstractColleague {
private String strAttribute;
public ConcreteColleagueB(String str) {
this.strAttribute = str;
}
@Override
public void changeString(String str) {
this.strAttribute = this.strAttribute + "這是同事A對我的影響:" + str;
}
@Override
public void setString(String str, AbstractMediator am) {
am.bChangedA(str);
}
public String getStrAttribute() {
return strAttribute;
}
}
具體中介者類:
public class ConcreteMediator implements AbstractMediator {
// 持有並維護同事A
private ConcreteColleagueA colleagueA;
// 持有並維護同事B
private ConcreteColleagueB colleagueB;
// 傳入同事A的對象
public void setColleagueA(ConcreteColleagueA colleagueA) {
this.colleagueA = colleagueA;
}
// 傳入同事B的對象
public void setColleagueB(ConcreteColleagueB colleagueB) {
this.colleagueB = colleagueB;
}
/**
* 收到同事A的改變,通知同事B改變
*/
@Override
public void aChangedB(String str) {
colleagueB.changeString(str);
}
/**
* 收到同事B的改變,通知同事A改變
*/
@Override
public void bChangedA(String str) {
colleagueA.changeString(str);
}
}
客戶端測試類:
public class Client {
public static void main(String[] args) {
// 實例化同事A、B
ConcreteColleagueA colleagueA = new ConcreteColleagueA("大家好,我是同事A。");
ConcreteColleagueB colleagueB = new ConcreteColleagueB("大家好,我是同事B。");
// 同時把同事A、B傳入給中介者
ConcreteMediator am = new ConcreteMediator();
am.setColleagueA(colleagueA);
am.setColleagueB(colleagueB);
// 同事A影響同事B
System.out.println(colleagueB.getStrAttribute());
colleagueA.setString("同事A傳遞給同事B的值", am);
System.out.println(colleagueB.getStrAttribute());
System.out.println("==========================");
// 同事B影響同事A
System.out.println(colleagueA.getStrAttribute());
colleagueB.setString("同事B傳遞給同事A的值", am);
System.out.println(colleagueA.getStrAttribute());
}
}
運行結果:
5. 中介者模式的優缺點:
中介者模式的優點:
- 使用中介者模式可以把對個同事對象之間的交互封裝到中介者對象裏面,從而使得同事對象之間鬆散耦合。
- 中介者模式可以將原先多對多的同事對象關係變成中介者對象一對多同事對象的關係,這樣會讓對象之間的關係更容易理解和實現。
- 同事對象之間的交互都被封裝到中介者對象裏面集中管理,集中了控制交互。當交互發生改變時,着重修改的是中介者對象。當需要擴展中介者對象時,其他同事對象不需要做修改。
缺點:
- 過度集中化,這是中介者模式潛在的缺點。如果同事對象多了,交互也複雜了。那麼這些交互全部集中到中介者對象中,會導致中介者對象十分臃腫,難以管理和維護。
參考原文: https://blog.csdn.net/jsagacity/article/details/79032608