三分钟理解“中介者模式”——设计模式轻松掌握

中介者模式的官方定义:

中介者模式使用一个中介对象来封装一系列对象的交互,从而使各对象不需要显式的相互引用,从而使得对象我们耦合松散,而且可以独立地改变对象之间的交互。

普通情况下ColleagueA向ColleagueB、ColleagueC、ColleagueD对象发送消息:

1.首先,在ColleagueA类中需要有一个sendMessage函数,用于向指定的对象发送消息;

2.其次,所有需要接收消息的对象都必须实现Colleague接口,并实现其中的getMessage函数,用于接收消息。

3.sendMessage()函数的实现如下:

private ColleagueB b = new ColleagueB();

private ColleagueC c = new ColleagueC();

private ColleagueD d = new ColleagueD();

public boolean sendMessage(String mess,Colleague colleague){

if(colleague instanceof(ColleagueB))

b.getMessage(message);

else if(colleague instanceof(ColleagueB))

c.getMessage(message);

else if(colleague instanceof(ColleagueB))

d.getMessage(message);

}

在ColleagueA中必须要先创建ColleagueB、ColleagueC、ColleagueD三个对象,然后调用他们各自的getMessage函数给他们发送消息。

在这种方式中,ColleagueA直接向三个对象发送消息,也就是ColleagueA必须要拥有其他三个对象的引用,这样导致ColleagueA与其他三个对象的藕合度高;若要增加消息接收者的时候,就必须要修改ColleagueA中的代码,这违背了“开放扩展,封闭修改”的原则。

使用“中介者模式”向ColleagueA向ColleagueB、ColleagueC、ColleagueD对象发送消息:

引入中介者之后,ColleagueA中只需要包含Mediator对象,无需发送函数;ColleagueA若要向ColleagueB、ColleagueC、ColleagueD发送消息,只需调用Mediator对象的sendMessage(message,colleague)即可。

由于A只与Mediator打交道,与B、C、D并没有直接的关系,因此实现了A与BCD之间的松藕合。

若要增加接收消息的类,只需在Mediator中增加代码,而无需修改ColleagueA中的代码,从而体现了“开放扩展,封闭修改”。

PS:“开放-封闭”原则是针对客户端而言的,是指当调用者/用户使用了一个类库之后,如果类库的功能要增强的时候,客户端代码应该是不需要做任何修改的,这就体现了“封闭修改”的原则,也就是“封闭修改”是针对客户端而言的,被调用的类库中仍然可能有部分代码需要修改,这是允许的。

中介者模式的优点:

Mediator的出现减少了各个Colleague之间的藕合,使得可以独立地改变和复用各个Colleague和Mediator;

其次,由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。

中介者模式的缺点:

由于Mediator中包含了所有的Colleague对象,所有的控制都在Mediator的sendMessage函数中实现,从而使得中介者过于复杂。

何时运用?

中介者模式一般应用于一组对象之间的通信较为复杂,采用中介者连接所有对象,从而降低各个对象之间的藕合度。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JavaEdge

类加载器与双亲委派模型1 类加载器 2 双亲委派模型

类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因。 在类加载的第一阶段“加载”过程中,需要通过一个类的全限定名来获取...

1142
来自专栏fixzd

[代码结构设计]根据不同条件使用不同实现类的业务代码设计

这样大家可能不是太理解。举个例子,现在大街小巷上的商户都采用了聚合支付的支付方式,聚合支付也就是商户柜台前放了一个支持支付宝、微信、京东钱包、银联等等的二维码,...

1004
来自专栏Android中高级开发

Android并发编程 多线程与锁

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,如果能给各位看官带来一丝启发或者帮助,那真是极好的。

1016
来自专栏FreeBuf

FlaskJinja2 开发中遇到的的服务端注入问题研究 II

0x00. 前言 本篇文章是 《Flask Jinja2 开发中遇到的的服务端注入问题研究》<点击阅读原文查看链接>续篇,我们继续研究 Flask Jinja...

2756
来自专栏calmound

多线程入门

HANDLE WINAPI CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE...

3186
来自专栏Greenplum

Linux 常用命令(五)

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

880
来自专栏码代码的陈同学

Java中的类加载器

Class loaders属于JRE的一部分,负责在运行时将Java类动态加载到JVM。得益于class loaders,JVM在无需知晓底层文件或文件系统时就...

912
来自专栏技术博客

Asp.Net Web API 2第十四课——Content Negotiation(内容协商)

阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.h...

811
来自专栏高爽的专栏

Java线程(四):线程中断、线程让步、线程睡眠、线程合并

最近在Review线程专栏,修改了诸多之前描述不够严谨的地方,凡是带有Review标记的文章都是修改过了。本篇文章是插进来的,因为原来没有写,现在...

2390
来自专栏向治洪

Koa源码分析

Koa 是一个类似于 Express 的Web开发框架,创始人也都是TJ。Koa 的主要特点是,使用了 ES6 的 Generator 函数,进行了架构的重新设...

2816

扫码关注云+社区