折腾Java设计模式之中介者模式
博文原址:折腾Java设计模式之中介者模式
中介者模式
中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。
通俗点来讲就是提供一个中介平台,说到平台,那其实很容易联系到我们很熟悉的房地产中介。我们可以直接通过这个平台得到我们想要的信息,不用对象自身与其他对象交互。
买房子租房子就不需要去找房东,只需要在中介那里获取相应的房产信息。如下图那样,两方只需要找中介即可。
再来看一张对比图。
有没有感觉没有使用之前,对象间互相依赖互相调用,错综复杂,盘根错节,当加入中介者后,对象间的关系一目了然,清晰明了。由中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。
中介者模式UML图
UML类图和时序图
collague1和collague2类不直接相互依赖,它们是用起控制和协调交互作用的公共中介接口(mediate()方法),这使它们有独立交互的执行方式。mediate1类实现collague1和collague2之间的依赖。
中介者模式角色
抽象中介者(Mediator): 定义了同事对象到中介者对象之间的接口。
具体中介者(ConcreteMediator): 实现抽象中介者的方法,它需要知道所有的具体同事类,同时需要从具体的同事类那里接收信息,并且向具体的同事类发送信息。
抽象同事类(Colleague): 定义了中介者对象的接口,它只知道中介者而不知道其他的同事对象。
具体同事类(ConcreteColleague) : 每个具体同事类都只需要知道自己的行为即可,但是他们都需要认识中介者。
示例代码
抽象中介者
@Slf4j
public abstract class Mediator {
/**
* 房东map
*/
protected Map<People, Message> landlordMap = Maps.newHashMap();
/**
* 租户列表
*/
protected List<People> renterList = Lists.newArrayList();
/**
* 注册房东信息
*
* @param landlord 房东
* @param message 房屋信息
*/
public void registerLandlord(People landlord, Message message) {
landlordMap.put(landlord, message);
log.info("中介信息:房东|{}|加入到中介平台,房屋信息:{}", landlord.getName(), message);
}
/**
* 变更房东信息
*
* @param landlord 房东
* @param message 房屋信息
*/
protected void modifyLandlordInfo(People landlord, Message message) {
landlordMap.put(landlord, message);
log.info("中介信息:房东|{}|修改他在中介平台的房屋信息,现房屋信息:{}", landlord.getName(), message);
}
/**
* 注册租户信息
*
* @param renter 租户
*/
public void registerRenter(People renter) {
renterList.add(renter);
log.info("中介信息:租户|{}|来中介平台租房", renter.getName());
}
/**
* 声明抽象方法 由具体中介者子类实现 消息的中转和协调
*/
public abstract void operation(People people, Message message);
}
抽象同事类
@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class People {
private Mediator mediator;
private String name;
/**
* 向中介发送消息
*/
protected abstract void sendMessage(Message message);
/**
* 从中介获取消息
*/
protected abstract void getMessage(Message message);
}
具体同事类 房东和租户
@Slf4j
public class Landlord extends People {
public Landlord(Mediator mediator, String name) {
super(mediator, name);
}
@Override
protected void sendMessage(Message message) {
getMediator().operation(this, message);
}
@Override
protected void getMessage(Message message) {
log.info("房东|{}|从中介获取到租户的信息:{}", getName(), message);
}
}
@Slf4j
public class Renter extends People {
public Renter(Mediator mediator, String name) {
super(mediator, name);
}
@Override
protected void sendMessage(Message message) {
getMediator().operation(this, message);
}
@Override
protected void getMessage(Message message) {
log.info("租户|{}|从中介获取到房东的信息:{}", getName(), message);
}
}
具体中介者
public class RealEstateAgent extends Mediator {
@Override
public void operation(People people, Message message) {
if (people instanceof Renter) {
// 将租户的租房条件信息发送给房东们
landlordMap.keySet().forEach(landlord -> landlord.getMessage(message));
// 租户收到中介那里房东的房屋信息
landlordMap.values().forEach(messages -> people.getMessage(messages));
} else if (people instanceof Landlord) {
// 将房东的房屋信息发送给租户们
renterList.forEach(renter -> renter.getMessage(message));
// 变更中介里的房东房屋信息
modifyLandlordInfo(people, message);
}
}
}
客户端
@Slf4j
public class Client {
public static void main(String[] args) {
Mediator mediator = new RealEstateAgent();
People laoWang = new Landlord(mediator, "老王");
People laoLee = new Landlord(mediator, "老李");
People laoBai = new Landlord(mediator, "老白");
People xiaoSan = new Renter(mediator, "小3");
People xiaoWang = new Renter(mediator, "小王");
mediator.registerLandlord(laoWang, Message.builder().msg("我这有2500的房子,市中心").build());
mediator.registerLandlord(laoBai, Message.builder().msg("我这有2000的房子,地铁旁").build());
mediator.registerLandlord(laoLee, Message.builder().msg("我这有2000的房子,落地阳台,大空间,采光好,地铁旁").build());
mediator.registerRenter(xiaoSan);
log.info("小3开始找房子");
xiaoSan.sendMessage(Message.builder().msg("想找个月租2000块的房子,靠近地铁").build());
log.info("没过多久---------老白升级了房屋信息");
laoBai.sendMessage(Message.builder().msg("我这有2000的房子,地铁旁,我又加了空调和热水器").build());
mediator.registerRenter(xiaoWang);
log.info("小王开始找房子");
xiaoWang.sendMessage(Message.builder().msg("想找个月租2500块的房子,靠近地铁").build());
log.info("没过多久---------老李也升级了房屋信息");
laoBai.sendMessage(Message.builder().msg("我这有2000的房子,落地阳台,大空间,采光好,地铁旁,我也加了空调和热水器").build());
}
}
最终出效果的如下
现在我来分析下里面各个角色的作用:
首先先分析两个抽象类。抽象同事类,含有名称和中介者的引用,有2个方法从中介拿信息和发信息给中介。抽象中介者,其中含有房东的map信息,key为房东数据,value为房东的房屋信息,用来房东注册和房东房屋信息变更;租户的列表信息,供租户注册,同时还有个协调方法,用于协调房东和租户。
具体抽象类(房地产中介),实现了抽象中介者的协调方法,当租户发送消息时,将租户的租房条件信息发送给所有房东们同时该租户收到中介那里所有房东的房屋信息;当房东发送消息时,将房东的房屋信息发送给所有租户们同时变更中介里的改房东房屋信息。
具体同事实现类(房东和租户),实现了抽象同事类的读取消息方法和发送消息方法(该房屋就是依靠中介者的协调方法来实现)。
JDK中的应用
通过使用一个中间对象来进行消息分发以及减少类之间的直接依赖。
java.util.Timer
java.util.concurrent.Executor#execute()
java.util.concurrent.ExecutorService#submit()
java.lang.reflect.Method#invoke()
总结
优点
使用中介者模式可以把对个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合。
中介者模式可以将原先多对多的同事对象关系变成中介者对象一对多同事对象的关系,这样会让对象之间的关系更容易理解和实现。
同事对象之间的交互都被封装到中介者对象里面集中管理,集中了控制交互。当交互发生改变时,着重修改的是中介者对象。当需要扩展中介者对象时,其他同事对象不需要做修改。
缺点
如果同事对象多了,交互也复杂了。中介者会庞大,变得复杂难以维护。
参考
JAVA设计模式之 中介者模式【Mediator Pattern】
欢迎关注
折腾Java设计模式之中介者模式的更多相关文章
- 从中国加入WTO来看Java设计模式:中介者模式
目录 应用场景 中介者模式 定义 意图 主要解决问题 何时使用 优缺点 世界贸易组织WTO 应用场景 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象 想通过一个 ...
- Java 设计模式之中介者模式
本文继续23种设计模式系列之中介者模式. 定义 用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互. 角色 抽象中介者: ...
- java设计模式之中介者模式
中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式UML图 中介者模式代码 package com ...
- Java 设计模式 之 中介者模式(Mediator)
中介者的功能非常简单,就是封装对象之间的交互. 如果一个对象的操作会引起其他相关对象的变化,或者是某个操作需要引起其他对象的后续或连带操作,而这个对象又不希望自己来处理这些关系,那么久可以找中介者,把 ...
- 18.java设计模式之中介者模式
基本需求 智能家庭包括各种设备,闹钟.咖啡机.电视机.窗帘等 要看电视时,各个设备可以协同工作,自动完成看电视的准备工作,比如流程为:闹铃响起->咖啡机开始做咖啡->窗帘自动落下-> ...
- 折腾Java设计模式之建造者模式
博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...
- 折腾Java设计模式之备忘录模式
原文地址:折腾Java设计模式之备忘录模式 备忘录模式 Without violating encapsulation, capture and externalize an object's int ...
- 折腾Java设计模式之状态模式
原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...
- 折腾Java设计模式之模板方法模式
博客原文地址:折腾Java设计模式之模板方法模式 模板方法模式 Define the skeleton of an algorithm in an operation, deferring some ...
随机推荐
- webpack Code Splitting浅析
Code Splitting是webpack的一个重要特性,他允许你将代码打包生成多个bundle.对多页应用来说,它是必须的,因为必须要配置多个入口生成多个bundle:对于单页应用来说,如果只打包 ...
- C++解析头文件-Qt自动生成信号声明
目录 一.瞎白话 二.背景 三.思路分析 四.代码讲解 1.类图 2.内存结构声明 3.QtHeaderDescription 4.私有函数讲解 五.分析结果 六.下载 一.瞎白话 时间过的ZTMK, ...
- MIP 内容声明
从搜索结果页点出的 MIP 页面,其页面上的任何内容(包括但不限于广告.在线咨询.统计等组件)均视为在原站点上的投放和使用. MIP (Mobile Instant Pages - 移动网页加速器), ...
- 如何看MySql执行计划explain(或desc)
简介 MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性优化.EXPLAIN 命令用法十分简单, 在 S ...
- 循环神经网络(Recurrent Neural Network,RNN)
为什么使用序列模型(sequence model)?标准的全连接神经网络(fully connected neural network)处理序列会有两个问题:1)全连接神经网络输入层和输出层长度固定, ...
- WebView,我已经长大了,知道自己区分是否安全了!
一.前言 如果你在用 Android 原生系统(Google Play 服务),在使用 WebView 加载某些网页时,一定遇到过以下的安全警告红屏. 这是 WebView 的安全浏览保护策略,在 A ...
- mqtt服务器apollo的搭建和测试工具paho的使用
(1)前言 MQTT协议是IBM开发的一个即时通讯协议; 基于发布/订阅的消息协议,近些年来被广泛应用于能源.电力.....等硬件性能低下的远程设备,此外国内很多企业使用MQTT作为android手机 ...
- 设计模式 | 抽象工厂模式(abstract factory)
定义: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类. 结构:(书中图,侵删) 这个图相对来说有一点点复杂,其实就是在工厂方法模式的基础上做了一些扩展,工厂方法模式只用于生成一种 ...
- ArcGIS API for JavaScript 入门教程[6] 再讲数据——Map类之可操作图层
[回顾]上篇交代了Map是各种图层(不管是实际上的图层还是由图层构成的对象)的容器,是数据的容器,并不作显示(由视图类绘制).并重点讲解了由图层构成的复杂图层——高程属性ground和底图属性base ...
- IO_ADDRESS()的实现【转】
上面我们说了如何去在系统中自己实现一个设置系统寄存器的一个方法,上面归根到底要进行物理地址到虚拟地址的映射 现在我们就说说IO_ADDRESS()的实现 #define __REG32ALI(addr ...