一、中介者模式介绍
1. 解决的问题
次要解决当对象与对象之间存在大量关联关系时,若一个对象产生扭转,要跟踪与之相干的对象,同时做出相应解决的问题。
2. 定义
中介者模式是一种行为设计模式,能缩小对象之间凌乱无序的依赖关系。该模式会限度对象之间的间接交互,迫使它们通过一个中介者对象进行单干。
3. 利用场景
- 当一些对象与其余对象严密耦合以至于难以对其进行批改时,可应用中介者模式。
- 当组件因过于依赖其余组件而无奈在不同利用中复用时,可应用中介者模式。
- 为了在不同情景下复用一些根本行为,导致须要被迫创立大量组件子类时,可应用终结者模式。
二、中介者模式优缺点
1. 长处
- 繁多职责准则:能够将多个组件间的交换抽取到同一地位,使其更易于了解和保护。
- 开闭准则:无需批改理论组件就能减少新的中介者。
- 能够加重利用中多个组件的耦合状况。
- 能够更不便地复用各个组件。
2. 毛病
- 一段时间后,中介者可能会演变为上帝对象。
三、中介者模式利用实例:菜鸟驿站
1. 实例场景
置信大家平时快递来不及拿的话,大部分时候都会抉择让快递小哥将快递放到菜鸟驿站,咱们在放学/上班后再去菜鸟驿站拿本人的快递。同时,咱们如果有快递须要寄出,也是当初菜鸟驿站填写寄件单,而后快递小哥从菜鸟驿站拿到快递,发货。
其实在这里,菜鸟驿站就是一个中介者,承当着快递小哥和咱们之间的重要交换枢纽。
明天,咱们就以菜鸟驿站为例,介绍一下中介者模式。
2. 中介者模式实现
2.1 工程构造
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
2.2 代码实现
2.2.1 实体类
快递包裹
/** * 快递包裹 */@Getter@Setter@AllArgsConstructorpublic class ExpressPackage { /** * 包裹id */ private String id; /** * 包裹名称 */ private String name; /** * 收件人电话 */ private String consigneePhoneNumber; /** * 发件快递站 */ private CourierStation sendCourierStation; /** * 收件快递站 */ private CourierStation receiveCourierStation;}
快递员
/** * 快递员 */@Slf4j@Getter@Setter@AllArgsConstructorpublic 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@AllArgsConstructorpublic class User { /** * 用户id */ private String id; /** * 用户姓名 */ private String name; /** * 用户电话 */ private String phone; /** * 寄快递(快递放到快递站) * * @param expressPackage 快递包裹 */ public void sendExpressPackage(ExpressPackage expressPackage) { expressPackage.getSendCourierStation().sendExpressPackage(expressPackage); }}
2.2.2 服务类
快递站中介者
/** * 快递站 */public interface CourierStation { /** * 收件服务 * * @param expressPackage 快递包裹 */ void receiveExpressPackage(ExpressPackage expressPackage); /** * 寄件服务 * * @param expressPackage 快递包裹 */ void sendExpressPackage(ExpressPackage expressPackage);}
菜鸟驿站
/** * 菜鸟驿站 */@Slf4j@Getter@Setterpublic 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); } }}
2.3 测试验证
2.3.1 测试验证类
/** * 快递站测试类 */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); }}
2.3.2 测试后果
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
四、中介者模式构造
- 组件(Component)是蕴含各种业务逻辑的类。每个组件都有一个指向中介者的援用,该援用被申明为中介者接口类型。组件不晓得中介者理论所属的类,因而可通过连贯到不同的中介者使其能在其余程序中复用。
- 中介者(Mediator)接口申明了与组件交换的办法,但通常仅蕴含一个告诉办法。组件可将任意上下文(包含本身对象)作为该办法的参数,只有这样接管组件和发送者类才不会耦合。
- 具体中介者(Concrete Mediator)封装了多种组件间的关系。具体中介者通常会保留所有组件的援用并对其进行治理,甚至有时会对其生命周期进行治理。
组件并不知道其余组件的状况。如果组件内产生了重要事件,它只能告诉中介者。中介者收到告诉后能轻易确定发送者,这就足以判断下一步要触发的组件。
对于组件来说,中介者看上去齐全就是一个黑箱。发送者不晓得最终会由谁来解决本身的申请,接收者也不晓得申请到底来自于谁。
设计模式并不难学,其自身就是多年教训提炼出的开发指导思想,关键在于多加练习,带着应用设计模式的思维去优化代码,就能构建出更正当的代码。
源码地址:https://github.com/yiyufxst/design-pattern-java
参考资料:
小博哥重学设计模式:https://github.com/fuzhengwei/itstack-demo-design
深刻设计模式:https://refactoringguru.cn/design-patterns/catalog