主要解決當對象與對象之間存在大量關聯關係時,若一個對象發生改變,要跟蹤與之相關的對象,同時作出相應處理的問題。java
中介者模式是一種行爲設計模式,能減小對象之間混亂無序的依賴關係。該模式會限制對象之間的直接交互,迫使它們經過一箇中介者對象進行合做。git
相信你們平時快遞來不及拿的話,大部分時候都會選擇讓快遞小哥將快遞放到菜鳥驛站,咱們在放學/下班後再去菜鳥驛站拿本身的快遞。同時,咱們若是有快遞須要寄出,也是如今菜鳥驛站填寫寄件單,而後快遞小哥從菜鳥驛站拿到快遞,發貨。github
其實在這裏,菜鳥驛站就是一箇中介者,承擔着快遞小哥和咱們之間的重要交流樞紐。express
今天,咱們就以菜鳥驛站爲例,介紹一下中介者模式。設計模式
mediator-pattern └─ src ├─ main │ └─ java │ └─ org.design.pattern.mediator │ ├─ model │ │ ├─ ExpressPackage.java │ │ ├─ Courier.java │ │ └─ User.java │ └─ service │ ├─ CourierStation.java │ └─ impl │ └─ CaiNiaoCourierStation.java └─ test └─ java └─ org.design.pattern.mediator └─ CourierStationTest.java
快遞包裹併發
/** * 快遞包裹 */ @Getter @Setter @AllArgsConstructor public class ExpressPackage { /** * 包裹id */ private String id; /** * 包裹名稱 */ private String name; /** * 收件人電話 */ private String consigneePhoneNumber; /** * 發件快遞站 */ private CourierStation sendCourierStation; /** * 收件快遞站 */ private CourierStation receiveCourierStation; }
快遞員ide
/** * 快遞員 */ @Slf4j @Getter @Setter @AllArgsConstructor public class Courier { /** * 快遞員id */ private String id; /** * 快遞員姓名 */ private String name; /*** * 送快遞(放到快遞站) * * @param expressPackage 快遞包裹 */ public void sendExpressPackage(ExpressPackage expressPackage) { expressPackage.getReceiveCourierStation().receiveExpressPackage(expressPackage); } /** * 收快遞(從快遞站取件,併發貨) * * @param expressPackage 快遞包裹 */ public void receiveExpressPackage(ExpressPackage expressPackage) { log.info( "The courier {} has arrived in the hands of the express package {}, and it will be sent to you immediately.", this.getName(), expressPackage.getName() ); } }
用戶測試
/** * 用戶 */ @Getter @Setter @AllArgsConstructor public class User { /** * 用戶id */ private String id; /** * 用戶姓名 */ private String name; /** * 用戶電話 */ private String phone; /** * 寄快遞(快遞放到快遞站) * * @param expressPackage 快遞包裹 */ public void sendExpressPackage(ExpressPackage expressPackage) { expressPackage.getSendCourierStation().sendExpressPackage(expressPackage); } }
快遞站中介者優化
/** * 快遞站 */ public interface CourierStation { /** * 收件服務 * * @param expressPackage 快遞包裹 */ void receiveExpressPackage(ExpressPackage expressPackage); /** * 寄件服務 * * @param expressPackage 快遞包裹 */ void sendExpressPackage(ExpressPackage expressPackage); }
菜鳥驛站this
/** * 菜鳥驛站 */ @Slf4j @Getter @Setter public class CaiNiaoCourierStation implements org.design.pattern.mediator.service.CourierStation { /** * 快遞員列表 */ private List<Courier> courierList; /** * 收件服務 * * @param expressPackage 快遞包裹 */ @Override public void receiveExpressPackage(ExpressPackage expressPackage) { log.info( "The package {} has arrived at the cai niao courier station, please pick it up as soon as possible.", expressPackage.getName() ); } /** * 寄件服務 * * @param expressPackage 快遞包裹 */ @Override public void sendExpressPackage(ExpressPackage expressPackage) { Optional<Courier> courierOptional = courierList.stream().findAny(); if (courierOptional.isPresent()) { Courier courier = courierOptional.get(); courier.receiveExpressPackage(expressPackage); } } }
/** * 快遞站測試類 */ public class CourierStationTest { @Test public void testReceiveExpressPackage() { Courier courier = new Courier("1", "快遞小哥"); CaiNiaoCourierStation courierStation = new CaiNiaoCourierStation(); courierStation.setCourierList(Collections.singletonList(courier)); ExpressPackage expressPackage = new ExpressPackage( "1", "PS5", "13245678910", null, courierStation ); courier.sendExpressPackage(expressPackage); } @Test public void testSendExpressPackage() { User user = new User("1", "張三", "13245678910"); Courier courier = new Courier("1", "快遞小哥"); CaiNiaoCourierStation courierStation = new CaiNiaoCourierStation(); courierStation.setCourierList(Collections.singletonList(courier)); ExpressPackage expressPackage = new ExpressPackage( "1", "Kindle", "13245678910", courierStation, null ); user.sendExpressPackage(expressPackage); } }
22:19:52.811 [main] INFO o.d.p.m.s.impl.CaiNiaoCourierStation - The package PS5 has arrived at the cai niao courier station, please pick it up as soon as possible. 22:19:52.814 [main] INFO o.d.pattern.mediator.model.Courier - The courier 快遞小哥 has arrived in the hands of the express package Kindle, and it will be sent to you immediately. Process finished with exit code 0
組件並不知道其餘組件的狀況。若是組件內發生了重要事件,它只能通知中介者。中介者收到通知後能輕易肯定發送者,這就足以判斷下一步要觸發的組件。
對於組件來講,中介者看上去徹底就是一個黑箱。發送者不知道最終會由誰來處理自身的請求,接收者也不知道請求究竟來自於誰。
設計模式並不難學,其自己就是多年經驗提煉出的開發指導思想,關鍵在於多加練習,帶着使用設計模式的思想去優化代碼,就能構建出更合理的代碼。
源碼地址:https://github.com/yiyufxst/design-pattern-java
參考資料:
小博哥重學設計模式:https://github.com/fuzhengwei/itstack-demo-design
深刻設計模式:https://refactoringguru.cn/design-patterns/catalog