設計模式入門——中介者模式(mediator)
前言
-
- 中介者模式又稱為調停者模式,作為行為型的模式之一,本身是個很低調的模式,因為應用場合有限,所以不那麼被人熟知
- 下文我將舉例介紹中介者模式的作用,以及中介者模式應用的意義,文末我會總結一下中介者模式的一些特點
例項引入
假設現在科技發達之後,家裡所有裝置都是智慧化的,而小明在家洗澡的時候有個習慣就是喜歡聽歌,而且洗澡時候還要把窗簾拉上。因此就有這種情形,小明要拉窗簾可能就是要洗澡,當然也要聽歌,因此我們希望小明家的洗浴裝置,音響裝置和窗簾裝置都能協同合作,不管操作哪種裝置,其他兩種裝置都有一定響應,以此寫出程式。
程式上手
現在很明顯我們可以看出來,我們有三個物件,也就是三種裝置,程式看起來也很簡單,只要打卡一個裝置,這個裝置再開啟其他兩個裝置就好啦,只要在一個裝置的類裡放兩個其他裝置的 引用,很容易就搞定了,當然這樣最簡單啦,這樣寫出來的程式物件關係如下圖(這個程式我就不敲了)。
程式分析(當然這個程式能想像的到)
這個程式最主要的功能就是在 一個類裡完成了對另外兩個類的方法作用。但是這樣設計有兩個主要缺陷(其實是物件之間耦合度過高而引起的)
- 一旦窗簾裝置壞掉,需要更換,那樣我們就要讓新的窗簾裝置建立別的裝置的連線,這樣會很麻煩
- 如果我們又有別的需求,比如洗澡的時候要把門鎖住,那門鎖的智慧裝置又要關聯所有裝置,更加麻煩
引入中介者
中介者模式的引入則極大的彌補了上述程式的兩個缺陷,物件互動如下圖
其實中介者就好比智慧家居的管家,這樣所有物件的互動指令都通過它來傳達,這樣這個中介者負責與物件之間聯絡,物件與物件之間不再進行直接的互動,也就是對物件關係 進行解耦。下面我們就引入具體例子
中介者模式角色組成
抽象中介者(mediator) |
定義一個介面用於和物件通訊(SmartDevice) |
具體中介者(concretemediator) |
協調各同事物件實現協作,瞭解維護各個同事() |
抽象同事角色(colleague) |
規定了同事的基本型別 |
具體同事角色(concreteColleague) |
每個同事都知道中介者物件,要與同事通訊則把通訊告訴中介者 |
中介者模式一般類圖(我程式的類圖)
java
抽象同事類(智慧裝置)
package mediator_12;
public abstract class SmartDevice {
//相關裝置開啟之後 使其進入準備狀態
public abstract void readyState(String instruction);
//操作該裝置
public abstract void operateDevice(String instruction, SmartMediator mediator);
}
具體同事類1(窗簾裝置)
package mediator_12;
public class CurtainDevice extends SmartDevice{
public void operateDevice(String instruction,SmartMediator mediator) {
System.out.println("窗簾已"+instruction);//通過傳入指令,開啟或關閉窗簾
mediator.curtain(instruction);//窗簾通過中介者喚醒音樂裝置和洗浴裝置
}
public void readyState(String instruction) {
//如果其他裝置開啟則呼叫此方法,喚醒窗簾
System.out.println("窗簾裝置準備"+instruction);
}
}
具體同事類2(音響裝置)
package mediator_12;
public class MusicDevice extends SmartDevice{
public void operateDevice(String instruction,SmartMediator mediator) {
System.out.println("音樂裝置已"+instruction);
mediator.music(instruction);
}
public void readyState(String instruction) {
System.out.println("音樂裝置準備"+instruction);
}
}
具體同事類3(洗浴裝置)
package mediator_12;
public class BathDevice extends SmartDevice{
public void operateDevice(String instruction, SmartMediator mediator) {
System.out.println("洗浴裝置"+instruction);
mediator.bath(instruction);
}
public void readyState(String instruction) {
System.out.println("洗浴裝置正在準備"+instruction);
}
}
抽象中介者(中介裝置)
package mediator_12;
public abstract class SmartMediator {
//保留所有裝置的引用是為了當接收指令時可以喚醒其他裝置的操作
SmartDevice bd;
SmartDevice md;
SmartDevice cd;
public SmartMediator(SmartDevice bd, SmartDevice md, SmartDevice cd) {
super();
this.bd = bd;
this.md = md;
this.cd = cd;
}
public abstract void music(String instruction);
public abstract void curtain(String instruction);
public abstract void bath(String instruction);
}
具體中介者
package mediator_12;
public class ConcreteMediator extends SmartMediator{
public ConcreteMediator(SmartDevice bd, SmartDevice cd, SmartDevice md) {
super(bd, cd, md);
}
public void music(String instruction) {//音樂被喚醒後,使其他裝置進入準備狀態
cd.readyState(instruction);//呼叫窗簾的準備方法
bd.readyState(instruction);//呼叫洗浴裝置的準備方法
}
public void curtain(String instruction) {
md.readyState(instruction);
bd.readyState(instruction);
}
public void bath(String instruction) {
cd.readyState(instruction);
md.readyState(instruction);
}
}
客戶端
package mediator_12;
public class Client {
public static void main(String[] args) {
SmartDevice bd=new BathDevice();
SmartDevice cd=new CurtainDevice();
SmartDevice md=new MusicDevice();
SmartMediator sm=new ConcreteMediator(bd, cd, md);//把裝置引用都儲存在調停者中
cd.operateDevice("open",sm); //開啟窗簾
md.operateDevice("close",sm);//關閉音樂
}
}
執行結果
程式分析
- 首先我們要說這個程式解決了我上面說的兩個缺陷,現在我們不管是要新增裝置還是替換裝置,既然我們的裝置的關聯者只有中介者了,那麼修改一下中介者就好了。
- 之前我們是在自己裝置中就能聯絡其他裝置,現在我們把這種聯絡統統交給中介者去做。
- 不過可以看出現在的程式變的並不簡單,由於我們引入中介者,反而看起來程式變的更加複雜了 。
既然認識了中介者,現在我們在瞭解一下中介者的特點
作用
中介者物件封裝了一系列的物件互動,中介者使各物件不需要彼此聯絡來相互作用,從而使耦合鬆散,而且可以獨立的改變他們之間的互動。
應用場景
當有多個物件彼此間相互互動的時候,自然就會想到物件間的耦合度過高,解決辦法就是封裝物件間的互動行為,因此就能想到中介者模式就是幹這行的。
應用到的設計原則
高內聚,低耦合,使用中介者明顯降低了物件之間的耦合
中介者模式優點
- 通過讓物件彼此解耦,增加物件的複用性
- 通過將控制邏輯集中,可以簡化系統維護
- 通過中介者使一對所變成了一堆一,便於理解
缺點
- 如果涉及不好,引入中介者會使程式變的複雜
- 中介者承擔過多責任,維護不好會出大事