主要解决当对象与对象之间存在大量关联关系时,若一个对象发生改变,要跟踪与之相关的对象,同时作出相应处理的问题。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