行为型模式:中介者模式
LieBrother公众号原文: 行为型模式:中介者模式
十一大行为型模式之二:中介者模式。
简介
姓名 :中介者模式
英文名 :Mediator Pattern
价值观 :让你体验中介是无所不能的存在
个人介绍 :
Define an object that encapsulates how a set of objects interact.Mediator promotes loose coupling by keeping objects from referring to each other explicitly,and it lets you vary their interaction independently. 用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 (来自《设计模式之禅》)
你要的故事
看了这小伙子的名字,大家会很直观的想到那些拿了我们半个月租的租房中介同学。在这不讲讲房租中介同学,以后可没机会了。大家现在找房子,不管是买还是租,一登录什么安居客、58同城,是不是有 80% 是经纪人房源,说 80% 还是比较保守的,经历了 4 次找房,发现个人房源越来越少。每个网站都有个选项:经纪人房源。如下图:
(图片截自:安居客网站)
经纪人就扮演着中介的角色,和本文要讲的中介者模式完全吻合。我们在找房子的时候,经纪人扮演什么角色呢?我们通过个人房源和经纪人房源的租房案例来简单描述经纪人的角色。
个人房源
我们通过个人房源找房子的方式是这样的:在网上找个人房源的房东,然后挨个联系,和房东约定好时间去看房,我们跟房东的关系是一对多的关系。小明就在网上看了个人房源,联系了房东,分别去看了农民房和小区房,用代码表示如下。
public class PersonalTest { public static void main(String[] args) { Tenant xiaoMing = new Tenant("小明"); xiaoMing.lookAtHouse(); } } class Tenant { private String name; private XiaoQuFangLandlord xiaoQuFangLandlord2 = new XiaoQuFangLandlord(); private NongMinFangLandlord nongMinFangLandlord2 = new NongMinFangLandlord(); public Tenant(String name) { this.name = name; } public void lookAtHouse() { System.out.println(this.name +"想看农民房"); nongMinFangLandlord2.supply(); System.out.println(this.name + "想看小区房"); xiaoQuFangLandlord2.supply(); } } /** * 房东 */ abstract class Landlord { // 提供房子 public abstract void supply(); } class XiaoQuFangLandlord extends Landlord { @Override public void supply() { System.out.println("小区房的房东提供一间小区房"); } } class NongMinFangLandlord extends Landlord { @Override public void supply() { System.out.println("农民房的房东提供一间小区房"); } } 打印结果如下: 小明想看农民房 农民房的房东提供一间小区房 小明想看小区房 小区房的房东提供一间小区房
小明分别联系小区房的房东和农民房的房东,然后依次去看了农民房和小区房。这样子有个弊端就是小明和房东是强关联的关系,其实小明只是去看一下房,看完不想租就和房东没啥关系了。这个时候经纪人就派上用场了,经纪人的主要任务就是把房子租出去,所以他和房东应该是强关系,直到把房子成功租出去了,才和房东脱离关系,而小明也不用去挨个找房东看房子了,这个职责转给经纪人,小明只需要联系一个人,那就是经纪人,跟他说我要看小区房和农民房,经纪人就带他去看。下面就介绍经纪人房源的方式,也就是本文要讲的中介者模式。
经纪人房源
用经纪人房源找房子,小明就省心很多了,小明就只联系了一个经纪人,跟他描述了自己要的房源:小区房和农民房都可以,经纪人里面和他约定了一个下午的时间,把小明所有想看的房让他看完,最终小明决定租了一间房。看代码。
public class MediatorTest { public static void main(String[] args) { System.out.println("小明想要看小区房和农民房"); Tenant2 xiaoMing = new Tenant2("小明", Arrays.asList("XiaoQuFang", "NongMinFang")); xiaoMing.lookAtHouse(); } } /** * 租客 */ class Tenant2 { private String name; private List<String> wantTypes; private RentingMediator rentingMediator = new RentingMediator(); public Tenant2(String name, List<String> wantTypes) { this.name = name; this.wantTypes = wantTypes; } public void lookAtHouse() { rentingMediator.supplyHouse(wantTypes); } } /** * 中介抽象类 */ abstract class Mediator { // 看房 public abstract void supplyHouse(List<String> types); } /** * 租房中介 */ class RentingMediator extends Mediator { private XiaoQuFangLandlord xiaoQuFangLandlord; private NongMinFangLandlord nongMinFangLandlord; public RentingMediator() { xiaoQuFangLandlord = new XiaoQuFangLandlord(); nongMinFangLandlord = new NongMinFangLandlord(); } @Override public void supplyHouse(List<String> types) { System.out.println("经纪人提供了如下房源"); if (types.contains("XiaoQuFang")) { xiaoQuFangLandlord.supply(); } if (types.contains("NongMinFang")) { nongMinFangLandlord.supply(); } } } 打印结果: 小明想要看小区房和农民房 经纪人提供了如下房源 小区房的房东提供一间小区房 农民房的房东提供一间小区房
在代码中,我们可以看到小明和经纪人是一对一关系,经纪人和房东是一对多关系。小明找房经历也轻松多了,只花了一下午就把房子都看了并看中了。这也是中介者模式的优点,减少了不必要的依赖,降低了类间的耦合。
代码: Mediator Pattern
总结
中介者模式通过在互相依赖的对象中间加了一层,让原本强依赖的对象变成弱依赖。在软件编程中,有一个中介者模式的典型的例子,就是 MVC 框架,也称三层架构,通过 Controller (控制层) 将 Model (业务逻辑层) 和 View (视图层) 的依赖给分离开,协调 Model 和 View 中的数据和界面交互工作。看看你工作中的代码,想想看有没有哪些对象之间的关系特紧密特混乱,考虑是不是可以通过中介者模式来把依赖关系剥离,让代码更清晰。
参考资料:《大话设计模式》、《设计模式之禅》
推荐阅读:
希望文章对您有所帮助,设计模式系列会持续更新,感兴趣的同学可以关注公众号:LieBrother,第一时间获取文章推送阅读,也可以一起交流,交个朋友。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
多线程知识回顾
以前看过不少JDK源码,最近回顾了一下笔记,所以在这里对几个很常见到的线程类做个记录。 一、ThreadLocal ThreadLocal是一个线程级的局部变量,“本地线程”只是俗称但并不准确。 假设是拿Map去做线程的局部变量,一般就两种思路:以Thread为key的共享区域,使用上不会有什么问题,但因为是共享区域访问,我们要做并发控制比如synchronized这样的悲观策略来保证线程安全,可同步会限制吞吐。第二种就是线程封闭,ThreadLocal正是使用了这种方式,线程本地维护一个区域ThreadLocalMap,以ThreadLocal实例为key,线程间数据隔离,自然就不存在线程安全的问题了。即ThreadLocal作为句柄、一个入口,来连接ThreadLocalMap和Thread。 内存泄漏问题:ThreadLocalMap的key使用了弱引用,指向某个ThreadLocal实例。当把ThreadLocal实例置为null后,那么它将会被GC回收。但ThreadLocalMap中的value不会被回收,因为存在一条current thread的强引用。因为Thre...
- 下一篇
自动机器学习简述(AutoML)
为什么需要自动机器学习 对于机器学习的新用户而言,使用机器学习算法的一个主要的障碍就是算法的性能受许多的设计决策影响。随着深度学习的流行,工程师需要选择相应的神经网络架构,训练过程,正则化方法,超参数,等等,所有的这些都对算法的性能有很大的影响。于是深度学习工程师也被戏称为调参工程师。 自动机器学习(AutoML)的目标就是使用自动化的数据驱动方式来做出上述的决策。用户只要提供数据,自动机器学习系统自动的决定最佳的方案。领域专家不再需要苦恼于学习各种机器学习的算法。 自动机器学习不光包括大家熟知的算法选择,超参数优化,和神经网络架构搜索,还覆盖机器学习工作流的每一步: 自动准备数据 自动特征选择 自动选择算法 超参数优化 自动流水线/工作流构建 神经网络架构搜索 自动模型选择和集成学习 超参数优化Hyper-parameter Optimization 学习器模型中一般有两类参数,一类是可以从数据中学习估计得到,还有一类参数时无法从数据中估计,只能靠人的经验进行设计指定,后者成为超参数。比如,支持向量机里面的C, Kernal, game;朴素贝叶斯里面的alpha等。 超参数优化有很...
相关文章
文章评论
共有0条评论来说两句吧...