折腾Java设计模式之中介者模式

时间:2022-09-22 19:21:10

博文原址:折腾Java设计模式之中介者模式

中介者模式

中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。

通俗点来讲就是提供一个中介平台,说到平台,那其实很容易联系到我们很熟悉的房地产中介。我们可以直接通过这个平台得到我们想要的信息,不用对象自身与其他对象交互。

买房子租房子就不需要去找房东,只需要在中介那里获取相应的房产信息。如下图那样,两方只需要找中介即可。

折腾Java设计模式之中介者模式

再来看一张对比图。

折腾Java设计模式之中介者模式

有没有感觉没有使用之前,对象间互相依赖互相调用,错综复杂,盘根错节,当加入中介者后,对象间的关系一目了然,清晰明了。由中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。

中介者模式UML图

UML类图和时序图

折腾Java设计模式之中介者模式

collague1和collague2类不直接相互依赖,它们是用起控制和协调交互作用的公共中介接口(mediate()方法),这使它们有独立交互的执行方式。mediate1类实现collague1和collague2之间的依赖。

中介者模式角色

折腾Java设计模式之中介者模式

抽象中介者(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()); }
}

最终出效果的如下

折腾Java设计模式之中介者模式

现在我来分析下里面各个角色的作用:

首先先分析两个抽象类。抽象同事类,含有名称和中介者的引用,有2个方法从中介拿信息和发信息给中介。抽象中介者,其中含有房东的map信息,key为房东数据,value为房东的房屋信息,用来房东注册和房东房屋信息变更;租户的列表信息,供租户注册,同时还有个协调方法,用于协调房东和租户。

具体抽象类(房地产中介),实现了抽象中介者的协调方法,当租户发送消息时,将租户的租房条件信息发送给所有房东们同时该租户收到中介那里所有房东的房屋信息;当房东发送消息时,将房东的房屋信息发送给所有租户们同时变更中介里的改房东房屋信息。

具体同事实现类(房东和租户),实现了抽象同事类的读取消息方法和发送消息方法(该房屋就是依靠中介者的协调方法来实现)。

JDK中的应用

通过使用一个中间对象来进行消息分发以及减少类之间的直接依赖。

java.util.Timer

java.util.concurrent.Executor#execute()

java.util.concurrent.ExecutorService#submit()

java.lang.reflect.Method#invoke()

总结

优点

使用中介者模式可以把对个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合。

中介者模式可以将原先多对多的同事对象关系变成中介者对象一对多同事对象的关系,这样会让对象之间的关系更容易理解和实现。

同事对象之间的交互都被封装到中介者对象里面集中管理,集中了控制交互。当交互发生改变时,着重修改的是中介者对象。当需要扩展中介者对象时,其他同事对象不需要做修改。

缺点

如果同事对象多了,交互也复杂了。中介者会庞大,变得复杂难以维护。

参考

中介者模式|菜鸟教程

Mediator pattern

细数JDK里的设计模式

JAVA设计模式之 中介者模式【Mediator Pattern】

欢迎关注

折腾Java设计模式之中介者模式

折腾Java设计模式之中介者模式的更多相关文章

  1. 从中国加入WTO来看Java设计模式:中介者模式

    目录 应用场景 中介者模式 定义 意图 主要解决问题 何时使用 优缺点 世界贸易组织WTO 应用场景 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象 想通过一个 ...

  2. Java 设计模式之中介者模式

    本文继续23种设计模式系列之中介者模式.   定义 用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互.   角色 抽象中介者: ...

  3. java设计模式之中介者模式

    中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式UML图 中介者模式代码 package com ...

  4. Java 设计模式 之 中介者模式(Mediator)

    中介者的功能非常简单,就是封装对象之间的交互. 如果一个对象的操作会引起其他相关对象的变化,或者是某个操作需要引起其他对象的后续或连带操作,而这个对象又不希望自己来处理这些关系,那么久可以找中介者,把 ...

  5. 18&period;java设计模式之中介者模式

    基本需求 智能家庭包括各种设备,闹钟.咖啡机.电视机.窗帘等 要看电视时,各个设备可以协同工作,自动完成看电视的准备工作,比如流程为:闹铃响起->咖啡机开始做咖啡->窗帘自动落下-> ...

  6. 折腾Java设计模式之建造者模式

    博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...

  7. 折腾Java设计模式之备忘录模式

    原文地址:折腾Java设计模式之备忘录模式 备忘录模式 Without violating encapsulation, capture and externalize an object's int ...

  8. 折腾Java设计模式之状态模式

    原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...

  9. 折腾Java设计模式之模板方法模式

    博客原文地址:折腾Java设计模式之模板方法模式 模板方法模式 Define the skeleton of an algorithm in an operation, deferring some ...

随机推荐

  1. H5拍照应用开发经历的那些坑儿

    一.项目简介 1.1.项目背景:这是一个在移动终端创新应用的项目,用户在浏览器端(微信/手Q)即可完成与金秀贤的合影,希望通过这样一种趣味体验,引发用户的分享与转发的热潮. 1.2.系统要求:ios6 ...

  2. ASP&period;NET MVC使用Bootstrap系列(4)——使用JavaScript插件

    阅读目录 序言 Data属性 VS 编程API 下拉菜单(dropdown.js) 模态框(modal.js) 标签页(tab.js) 工具提示(tooltip.js) 弹出框(popover.js) ...

  3. Java Hour 37 Weather &lpar; 10 &rpar;

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. Hour 36 Weather 从失败的地方爬起来 在jsp 中,使用EL 表 ...

  4. eclipse 文本编辑器

    Eclipse文本编辑器拥有编辑器的标准功能,包括数目不限的Undo(Ctrl+Z)和Redo(Ctrl+Y)操作.使用快捷键Ctrl+F后,会出现Find/Replace对话框,快捷键Ctrl+K或 ...

  5. HTML5拖放API

    拖放事件事件提供了拖放可以控制几乎所有方面的拖放操作.棘手的部分是确定每个事件触发:在拖项目火:别人火下降的目标.拖动项时,以下事件(按照这个顺序): 拖曳开始拖dragend此刻你把鼠标按钮和开始移 ...

  6. 如何不保存Word即可用Word打开想显示的内容!

    今天遇到客户需要将数据用Word预览,原来做的时候是保存到本地然后打开,客户说这样不好,因为不一定预览了一定要保存,于是我翻箱倒柜的发现真没资料啊!!幸好经过我的大量实验(好吧,我是挨个方法试的!), ...

  7. linux 命令 — sort、uniq

    sort uniq sort:对行或者文本文件排序 uniq:去除重复的行 常用 sort -n file.txt 按数字进行排序 sort -r file.txt 按逆序进行排序 sort -M f ...

  8. TensorFlow从入门到理解(一):搭建开发环境【基于Ubuntu18&period;04】

    *注:教程及本文章皆使用Python3+语言,执行.py文件都是用终端(如果使用Python2+和IDE都会和本文描述有点不符) 一.安装,测试,卸载 TensorFlow官网介绍得很全面,很完美了, ...

  9. stund客户端使用结果说明

    stun服务器是用于检测网络类型的重要工具. 源码地址:https://svwh.dl.sourceforge.net/project/stun/stun/0.97/stund-0.97.tgz 或者 ...

  10. 尚硅谷redis学习8-事务

    是什么? 能干嘛? 常用命令 案例说明 1.正常执行 2.放弃事务 3.全部放弃(全体连坐) 4.只抛弃错误(冤头债主) 5.watch监控 悲观锁 悲观锁(Pessimistic Lock), 顾名 ...