转自:JAVA设计模式之中介者模式,更好阅读体验:http://www.kongzid.com

中介者模式(Mediator)的定义

定义一个对象来封装一系列对象的交互,中介者模式使各个对象之间不需要相互引用,从而使得其松耦合,而且用户可以独立地改变他们之间的交互。(当这些对象中的某些对象之间的相互作用发生改变时,不会立即影响到其他的一些对象之间的相互作用。从而保证这些相互作用可以彼此独立地变化。)

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

核心:

  1. 如果一个对象中对象之间的联系呈现为网状结构,对象之间存在大量多对多的关系,将导致关系极其复杂,这些对象被称为“同事对象”.
  2. 我们可以引入一个中介者对象,使各个同事对象只跟中介者对象打交道,将复杂的网络结构化解为星形结构。

中介者模式(Mediator)优缺点

  1. 中介者模式是一种行为型设计模式,其主要优点如下:
  2. 使用中介者模式可以把对个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合。
  3. 中介者模式可以将原先多对多的同事对象关系变成中介者对象一对多同事对象的关系,这样会让对象之间的关系更容易理解、实现和扩展,将原本难以理解的网状结构换成相对接单的星状结构。
  4. 同事对象之间的交互都被封装到中介者对象里面集中管理,集中了控制交互。当交互发生改变时,着重修改的是中介者对象。当需要扩展中介者对象时,其他同事对象不需要做修改。(可以独立地改变和复用各个同事类和中介者。)
  5. 可以减少子类的生成。

缺点:

  1. 过度集中化,这是中介者模式潜在的缺点。如果同事对象多了,交互也复杂了。那么这些交互全部集中到中介者对象中(在具体中介中包含了大量的同事类之间的交互细节),会导致中介者对象十分臃肿(非常复杂),难以管理和维护。

适用环境:

  1. 系统中对象之间存在复杂的引用关系,系统结构混乱难以理解。
  2. 一个对象由于引用了其他很多对象并且直接和这些对象进行通信,导致难以复用该对象。
  3. 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

中介者模式(Mediator)的结构

中介者模式所涉及到的角色有:

  1. 抽象中介者角色(Mediator):定义一个接口用于与各同事对象之间进行通信,其中主要方法是一个(或多个)事件方法。
  2. 具体中介者角色(ConcreteMediator):实现抽象中介者中所声明的事件方法。具体中介者维持了对各个具体同事类对象的引用,并负责具体的协调各个同事对象的交互关系。
  3. 抽象同事类角色(Colleague):定义各个同事类对象共有的方法,并声明了一些抽象方法供子类实现,同时他维持了一个对抽象中介者类的引用,其子类可以通过该引用进行通讯。同事对象只知道中介者,而不知道其余的同事对象。
  4. 具体同事类角色(ConcreteColleague):所有的具体同事类均从抽象同事类继承而来。实现自己的业务,在需要与其他同事通信的时候,就与持有的中介者通信,中介者会负责与其他的同时交互。

中介者模式(Mediator)的应用实例

抽象的同事类:

public abstract class Colleague {private Mediator mediator;private String name;Colleague(String name,Mediator mediator){this.name  =name;this.mediator = mediator;}// getter/setter方法// 得到其他同事发来的信息public abstract void getMessage(String message,String messageFormName);// 与其他同事通信public abstract void contactColleague(String message,String ... toColleagueName);}

具体的同事:

public class ColleagueImpl extends Colleague {ColleagueImpl(String name, Mediator mediator) {super(name, mediator);}@Overridepublic void getMessage(String message,String messageFormName) {System.out.println("我" + this.getName() + " 被" + messageFormName + " 联系了, " + "信息为:" + message );}@Overridepublic void contactColleague(String message,String ... toColleagueNames) {System.out.print("我 " + this.getName() + " 向 ");for (String toColleagueName : toColleagueNames){System.out.print(toColleagueName + ",");}System.out.println(" 发 " + message + " 信息");this.getMediator().contact(message,this, toColleagueNames);}
}

抽象的中介:

/*** 抽象的中介者*/
public interface Mediator {/*** 中介者来使各同事之间的联系* @param content 交流内容* @param toColleagueNames 被联系者的名字*/void contact(String content,Colleague colleague,String ... toColleagueNames);/*** 添加同事* @param colleague 被添加的同事*/void addColleague(Colleague colleague);
}

具体的中介:

public class MediatorImpl implements Mediator {// 维护并知道所有同事。private Map<String,Colleague> colleagueMap = new HashMap<>();@Overridepublic void contact(String message,Colleague colleagueForm, String... toColleagueNames) {for (String name : toColleagueNames){Colleague colleague = colleagueMap.get(name);colleague.getMessage(message,colleagueForm.getName());}}@Overridepublic void addColleague(Colleague colleague) {this.colleagueMap.put(colleague.getName(),colleague);}
}

测试代码:

public class MediatorTest {public static void main(String[] args) {Mediator mediator = new MediatorImpl();Colleague colleagueA = new ColleagueImpl("小花",mediator);Colleague colleagueB = new ColleagueImpl("小明",mediator);Colleague colleagueC = new ColleagueImpl("小绿",mediator);Colleague colleagueD = new ColleagueImpl("小蓝",mediator);mediator.addColleague(colleagueA);mediator.addColleague(colleagueB);mediator.addColleague(colleagueC);mediator.addColleague(colleagueD);colleagueA.contactColleague("大家好",colleagueB.getName(),colleagueC.getName(),colleagueD.getName());}
}

测试结果:

我 小花 向 小明,小绿,小蓝, 发 大家好 信息
我小明 被小花 联系了, 信息为:大家好
我小绿 被小花 联系了, 信息为:大家好
我小蓝 被小花 联系了, 信息为:大家好

中介者模式(Mediator)的应用实例二

定义一个中介者接口及学委的接口:

//中介者接口类
public interface Mediator {//注册委员void register(String lname,ClassLeader c);//班长根据委员名字获得通知请求void command(String lname);}//班干部接口
public interface ClassLeader {//本职工作void job();//向班长提出请求void sendRequest();
}

具体学委角色:

//生活委员
public class LifeLeader implements ClassLeader {//持有对班长大人的引用private Mediator media;public LifeLeader(Mediator media) {super();this.media = media;media.register("LifeLeader", this);}@Overridepublic void job() {System.out.println("生活委员->小张最近生活作风有点问题,需要我的帮助!");}@Overridepublic void sendRequest() {System.out.println("生活委员->小张是不是有什么精神负担,班长大人去叫心理委员去看看什么情况吧!");media.command("phycologic");}
}//心理委员
public class PhychologicalLeader implements ClassLeader {//持有对班长大人的引用private Mediator media;public PhychologicalLeader(Mediator media) {super();this.media = media;media.register("phycologic", this);}@Overridepublic void job() {System.out.println("心理委员->小张最近心情好像不太好,需要我的帮助!");}@Overridepublic void sendRequest() {System.out.println("心理委员->小张是不是生活上有什么问题,班长大人叫生活委员多关注一下吧!");media.command("LifeLeader");}
}//学习委员
public class StudyLeader implements ClassLeader {//持有对班长大人的引用private Mediator media;public StudyLeader(Mediator media) {super();this.media = media;media.register("StudyLeader", this);}@Overridepublic void job() {System.out.println("学习委员->小张最近成绩突飞猛进,果然在我的英明指导下没有人能不起飞!");}@Overridepublic void sendRequest() {System.out.println("学习委员->小张为了成绩居然还搞抄袭,怎么变成这样了?班长大人快去通知生活委员和心理委员看看情况!");media.command("LifeLeader");media.command("phycologic");}
}

具体中介者角色:

//班长
public class ClassMonitor implements Mediator {//利用map集合存放学委的相关属性private Map<String,ClassLeader> map=new HashMap<String,ClassLeader>();//将对应名称的学委对象进行注册@Overridepublic void register(String lname, ClassLeader c) {map.put(lname, c);}//班长大人获取来自指定学委的请求通知@Overridepublic void command(String lname) {map.get(lname).job();}
}

客户端类:

public class Client {public static void main(String[] args) {Mediator m=new ClassMonitor();ClassLeader life=new LifeLeader(m);ClassLeader study=new StudyLeader(m);ClassLeader phycho=new PhychologicalLeader(m);//当前委员发送请求给班长然后通过班长与其他委员通信System.out.println("------生活委员->班长->心理委员------");life.sendRequest();System.out.println("--------------------------");System.out.println("------学习委员->班长->心理委员,生活委员------");study.sendRequest();System.out.println("--------------------------");System.out.println("------心理委员->班长->生活委员------");phycho.sendRequest();System.out.println("--------------------------");}
}

效果截图:

JAVA设计模式之中介者模式相关推荐

  1. Java设计模式之中介者模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

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

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

  3. 中介者模式java_图解Java设计模式之中介者模式

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

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

    在现实生活中,常常会出现好多对象之间存在复杂的交互关系,这种交互关系常常是"网状结构",它要求每个对象都必须知道它需要交互的对象.例如,每个人必须记住他(她)所有朋友的电话:而且, ...

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

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

  6. [Java]观察者模式和中介者模式改造机场

    [Java]观察者模式和中介者模式改造机场 文章目录 [Java]观察者模式和中介者模式改造机场 题目 代码部分 运行结果 补充 题目 请以下面的情景为基础,将以下的情景进行 优化: 1. 定义4个处 ...

  7. Java设计模式之行为型模式

    1 设计模式简介 软件设计模式是一套被反复使用的,多数人知晓的.经过分类编写.代码设计经验的总结.它描述了在软件设计过程中的一些不断重复发生的问题,以及该问题的解决方案,它是解决特定问题的一系列套路, ...

  8. 软件设计模式之中介者模式实验

    软件设计模式之中介者模式实验 一.实验目的 掌握软件设计模式中的中介者模式,能够用中介者模式编写程序,解决实际问题. 二.实验内容与要求 内容:有个租房中介为房主和租赁人提供租房服务,请用中介者模式对 ...

  9. 走穿java23种设计模式--18中介者模式详解

    走穿java23种设计模式–18中介者模式详解 中介者模式也称调停者模式,是一种比较简单的模式. 一.中介者模式的现实场景 蔡良因为上次表白时对方只看重他的物质方面,所以他对女朋友这个问题有点失望.因 ...

  10. 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)

    [索引页] [源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:webabcd 介绍 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互 ...

最新文章

  1. php接收不到ajax请求参数,我是否需要在ajax请求和接收该请求的php之间编码/解码查询参数?...
  2. 学会这些Python美图技巧,就等女朋友夸我了
  3. ICML 2021论文接收大排行!谷歌霸榜,国内北大第一、清华第二,华人学者表现亮眼.........
  4. zynq学习01 zynq 单独使用PL模块点亮led
  5. 开发文件上传功能稍不注意就会引发安全漏洞
  6. Http协议中Get和Post的浅谈
  7. PHP 发邮件《转》
  8. python 空指针_Python ctypes模块:扩展指针数组时进行NULL指针访问
  9. 【OpenGL从入门到精通(一)】Windows搭建OpenGL的渲染环境,并初始化一个OPenGL窗口
  10. Spring Boot 2 学习笔记(2 / 2)
  11. tika设置文件长度限制_MySQLInnoDB某些你没注意过的限制
  12. java小球游戏项目实战
  13. dos命令行设置网络优先级_网络工程师必知的Linux命令,精品!
  14. 利用struts2上传文件时,如果文件名中含有-符号,那么会出错
  15. Python24中使用urllib时遇到IOError的正确打开方式
  16. linux pvdisplay PE,linux中的pvmove,pvremove,pvs,pvscan
  17. Dear小弟×××,给你们的一封信「社区运营入门系列 序」
  18. Ubuntu 404 Not Found [IP: 91.189.95.85 80]解决办法
  19. 披荆斩棘Linux之清理空间
  20. PHP微勤,家E课 黄微勤 小学一年级作文二年级作文【写句子】百度...

热门文章

  1. 群晖docker实现IPV6访问
  2. SNN综述(1):深度脉冲神经网络
  3. python等待键盘输入_Pythoninput实现等待键盘输入,超时返回缺省值,并且释放input...
  4. USYD悉尼大学DATA1002 详细作业解析Module3
  5. 取次花丛懒回顾,半缘修道半缘君
  6. IDEA 设置自动启动浏览器
  7. java entity tostring_EntityUtils.toString(entity)处理字符集问题解决
  8. 苹果app退款_app退款理由写什么好?苹果退款理由怎么写才好?
  9. virt-manage 使用
  10. HBuilder的mui登录模板修改登录页为非入口页面的方法