設計模式——中介模式
引言
假設有老趙、老錢、老孫三位房東,他們自己手裡有一套房租需要出租,但是又有不同的需求,於是相互商量:
可是出租房子的人畢竟很多,哪種房型好租,租什麼價格需要了解很多出租情況,而自己要與那麼多人交流需要花費很大的時間與精力……所以他們都不約而同地找到了中介,將自己房子出租的資訊放到了中介 ,讓中介去和租客互動,自己有什麼問題也可以直接找中介問,還能躺著收房租,只需要和中介打交道就可以了。
這就是中介者模式的應用場景。
中介者模式
定義
用一箇中介物件封裝一系列的物件互動,中介者使各物件不需要顯示地相互作用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。
通用類圖
Mediator 抽象中介者角色
抽象中介者角色定義統一的介面,用於各同事角色之間的通訊。
Concrete Mediator 具體中介者角色
具體中介者角色通過協調各同事角色實現協作行為,因此它必須依賴於各個同事角色。
Colleague 同事角色
每一個同事角色都知道中介者角色,而且與其他同事角色通訊的時候,一定要通過中介者角色協作。協作分為兩種,一種是本身的行為,比如自己狀態變化,獨立可以完成的行為;另一種是必須依賴中介者才能完成的行為,比如與其他同事角色通訊。
中介者例子
前提條件
老趙、老錢、老孫的房子資訊如下:
- 老趙:一套一室一廚一衛房子
- 老錢:一套一室一廳一衛的房子
- 老孫:一套兩室一廳一廚一衛的房子
老趙感覺自己房子(一室一廚一衛)比老錢房子(一室一廳一衛)好出租,想比老錢的房子多租100元,如果老錢不告訴他自己的價格,那麼老趙就準備按2500出租;
老錢就想租2500,且想知道老趙和老孫的房子出租的資訊;
老孫覺得自己房子適合一家人住一起,想租3600,並且自己想知道小戶型房子(老趙和老孫房子)出租情況;
關係類圖
Mediator:抽象中介者
LettingAgent:具體的中介者實現
AbstractLessor:抽象的同事類(非必須)
XXXLessor:具體的同事類(多個出租人之間關係對等,類似同事關係)
程式碼實現
對於中介mediator來說,它指定老趙、老錢、老孫的資訊,他們可以通過詢問中介來知道自己想知道的事情,不需要單獨分別去問另外兩人,物件之間的依賴更簡單了,中介實現如下:
public abstract class Mediator { protected MrZhaoLessor mrZhaoLessor; protected MrQianLessor mrQianLessor; protected MrSunLessor mrSunLessor; public Mediator(){ this.mrZhaoLessor = new MrZhaoLessor(this); this.mrQianLessor = new MrQianLessor(this); this.mrSunLessor = new MrSunLessor(this); } public MrZhaoLessor getMrZhaoLessor() { return mrZhaoLessor; } public void setMrZhaoLessor(MrZhaoLessor mrZhaoLessor) { this.mrZhaoLessor = mrZhaoLessor; } public MrQianLessor getMrQianLessor() { return mrQianLessor; } public void setMrQianLessor(MrQianLessor mrQianLessor) { this.mrQianLessor = mrQianLessor; } public MrSunLessor getMrSunLessor() { return mrSunLessor; } public void setMrSunLessor(MrSunLessor mrSunLessor) { this.mrSunLessor = mrSunLessor; } public abstract String getZhaoAndQianInfo(); public abstract String getZhaoAndSunInfo(); public abstract String getQianAndSunInfo(); public abstract String getAllRoomInfo(); public abstract String getAllRoomPrice(); }
具體中介者實現了抽象中介者的方法:
public class LettingAgent extends Mediator { @Override public String getAllRoomInfo() { String roomInfo = "我手裡有這幾種房型:\n" + super.getMrZhaoLessor().roomInfo() + "\n" + super.getMrQianLessor().roomInfo() + "\n" + super.getMrSunLessor().roomInfo(); return roomInfo; } @Override public String getAllRoomPrice() { String roomPrice = super.getMrZhaoLessor().roomInfo() + ",價格:" + super.getMrZhaoLessor().roomPrice() + "\n" + super.getMrQianLessor().roomInfo() + ",價格:" + super.getMrQianLessor().roomPrice() + "\n" + super.getMrSunLessor().roomInfo() + ",價格:" + super.getMrSunLessor().roomPrice(); return roomPrice; } @Override public String getZhaoAndQianInfo(){ String otherRoom = super.getMrZhaoLessor().roomInfo() + ",價格:" + super.getMrZhaoLessor().roomPrice() + "\n" + super.getMrQianLessor().roomInfo() + ",價格:" + super.getMrQianLessor().roomPrice(); return otherRoom; } @Override public String getZhaoAndSunInfo(){ String otherRoom = super.getMrZhaoLessor().roomInfo() + ",價格:" + super.getMrZhaoLessor().roomPrice() + "\n" + super.getMrSunLessor().roomInfo() + ",價格:" + super.getMrSunLessor().roomPrice(); return otherRoom; } @Override public String getQianAndSunInfo(){ String otherRoom = super.getMrQianLessor().roomInfo() + ",價格:" + super.getMrQianLessor().roomPrice() + "\n" + super.getMrSunLessor().roomInfo() + ",價格:" + super.getMrSunLessor().roomPrice(); return otherRoom; } }
可以根據出租人之間是否有相同需求來決定是否需要增加出租人抽象介面
public abstract class AbstractLessor { protected Mediator mediator; public AbstractLessor(Mediator mediator){ this.mediator = mediator; } }
老趙的實現如下:
public class MrZhaoLessor extends AbstractLessor { public MrZhaoLessor(Mediator mediator) { super(mediator); } public String roomInfo() { return "老趙的一室一廚一衛"; } public BigDecimal roomPrice() { BigDecimal roomWithKitchAndToiletPrice = super.mediator.getMrQianLessor().roomPrice(); if (roomWithKitchAndToiletPrice == null) { //自己內心價格 return BigDecimal.valueOf(2500); } return roomWithKitchAndToiletPrice.add(BigDecimal.valueOf(100)); } public String talk() { return "很好租,獨立廚房衛生間"; } }
老錢與老孫實現差不多,以老錢為例:
public class MrQianLessor extends AbstractLessor { public MrQianLessor(Mediator mediator) { super(mediator); } public String roomInfo() { return "老錢的一室一廳一衛"; } public BigDecimal roomPrice() { return BigDecimal.valueOf(2500); } public String askOtherRoomInfo() { return super.mediator.getZhaoAndSunInfo(); } }
老趙與老錢通過中介互動:
LettingAgent agent = new LettingAgent(); MrZhaoLessor zhaoLessor = new MrZhaoLessor(agent); BigDecimal zhaoPrice = zhaoLessor.roomPrice(); String talk = zhaoLessor.talk(); System.out.println(">>>趙先生:\n" + zhaoPrice + ",\n" + talk+"\n"); MrQianLessor qianLessor = new MrQianLessor(agent); String qianRoom = qianLessor.askOtherRoomInfo(); System.out.println(">>>錢先生:\n" + qianRoom+"\n");
>>>趙先生:
2600,
很好租,獨立廚房衛生間
>>>錢先生:
老趙的一室一廚一衛,價格:2600
老孫的兩室一廳一廚一衛,價格:3600
總結
優點:減少類之間的依賴,引入中介者將原來多對多依賴便成了一對一,降低了類之間的耦合性。
缺點:中介者封裝了不同物件之間的依賴關係,當物件增多,中介者會變得很複雜,同事類越多中介者越複雜。
參考: ofollow,noindex">本文demo