1.1概述
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。这就是中介者模式的定义。
一个对象含有另一个对象的引用是面向对象中经常使用的方式,也是面向对象所提倡的,即少用继承多用组合。但是怎样合理地组合对象对系统今后的扩展、维护和对象的复用是至关重要的,这也正是学习设计模式的重要原因。
例如,在一个房屋租赁系统中,有很多对象,有些对象是求租者,有些是出租者,如果要求他们之间必须成为朋友才能进行有关租赁的操作,显然不利于系统的维护和发展,因此,每当有新的出租者或求租者加入该系统,这个新的加入者必须和现有系统中的所有人互为朋友后才能和他们进行有关租赁的操作,这就意味着要修改大量的代码,这对系统的维护是非常不利的也是无法容忍的。一个好的解决办法就是在房屋租赁系统中建立一个称作中介者的对象,中介者包含系统中所有其他对象的引用,而系统中的其他对象只包含中介者的引用,也就是说中介者和大家互为朋友、中介者使系统中的其他对象完全解耦,当系统中某个对象需要和系统中另外一个对象交互时,只需将自己的请求通知中介者即可,如果有新的加入者,该加入者只需含有中介者的引用,并让中介者含有自己的引用,他就可以和系统中其他对象进行有关租赁操作,具体如下图一所示:
图一:中介者、出租者和求租者
中介者模式是封装一系列的对象交互的成熟模式,其关键是将对象之间的交互封装在称作中介者的对象中,中介者使各对象不需要显示地相互吸引,这些对象只包含中介者的引用。当系统中某个对象需要和系统中另外一个对象交互时,只需要将自己的请求通知给中介者即可。
1.2模式的结构
中介者模式的结构包含四种角色:
(1)中介者(Mediator):中介者是一个接口,该接口定义了用于同事对象之间进行通信的方法。
(2)具体中介者(ConcreteMediator):具体中介者是实现中介者接口的类。具体中介者需要包含所有具体同事的引用,并通过实现中介者接口中的方法来满足具体同事之间的通信请求。
(3)同事(Colleague):一个接口,规定了具体同事需要实现的方法。
(4)具体同事(ConcreteColleague):实现同事接口的类。具体同事需要包含具体中介者的引用,一个具体同事需要和其他具体同事交互时,只需要将自己的请求通知给它所包含的具体中介者即可。
中介者模式结构的类图如下图二所示:
图二:中介者模式类图
1.3中介者模式的优点
(1)可以避免许多的对象为了通信而相互显示引用,否则,不仅系统难于维护,而且也使其他系统难以复用这些对象。
(2)可以通过中介者将原本分布于多个对象之间的交互行为集中在一起。当这些对象之间需要改变之间的通信行为时,只需要使用一个具体中介者即可,不必修改各个具体同事的代码,即这些同事可被重用。
(3)具体中介者使得各个具体同事完全解耦,修改任何一个具体同事的代码不会影响到其他同事。
(4)具体中介者集中了同事之间是如何交互的细节,使系统比较清楚地知道整个系统中的同事是如何交互的。
(5)当一些对象相互通信,但又无法相互包含对方的引用,那么使用中介者模式就可以使这些对象相互通信。
1.4适合使用中介者模式的情景
(1)许多对象以复杂的方式交互,所导致的依赖关系使系统难以理解和维护。
(2)一个对象引用其他很多对象,导致难以复用该对象。
1.5中介者模式的使用
以下通过一个简单的问题来描述中介者模式中所涉及的各个角色。
古代相互交战的A、B、C三方,想通过一个中介者调停之间的战火。A方委托调停者转达的信息是:“要求B方归还曾抢夺的100斤土豆,要求C方归还曾抢夺的20头牛”;B方委托调停者转达的信息是:“要求A方归还曾抢夺的10只公鸡,要求C方归还曾抢夺的15匹马”;C方委托调停者转达的信息是:“要求A方曾抢夺的360斤小麦,要求B方曾抢夺的50头驴”。
针对上述问题,使用中介者模式设计若干个类。具体如下:
首先看一下本实例构建框架具体类和1.2模式的结构中类图的对应关系,如下图所示:
(1)同事(Colleague)
本问题中,同事接口是Colleague,定义了具体同事,即交战各方需要实现的方法。Colleague接口的代码如下:
package com.liuzhen.nine_mediator; public interface Colleague { public void giveMess(String[] mess); public void receiverMess(String mess); public void setName(String name); public String getName(); }
(2)具体中介者(Mediator)
本问题中,只需要一个具体中介者,并不需要一个中介者接口,具体中介者是ConcreteMediator类,代码如下:
package com.liuzhen.nine_mediator; public class ConcreteMediator { ColleagueA colleagueA; ColleagueB colleagueB; ColleagueC colleagueC; public void registerColleagueA(ColleagueA colleagueA){ this.colleagueA = colleagueA; } public void registerColleagueB(ColleagueB colleagueB){ this.colleagueB = colleagueB; } public void registerColleagueC(ColleagueC colleagueC){ this.colleagueC = colleagueC; } public void deliveMess(Colleague colleague , String[] mess){ if(colleague == colleagueA){ if(mess.length >= 2){ colleagueB.receiverMess(colleague.getName()+mess[0]); colleagueC.receiverMess(colleague.getName()+mess[1]); } } if(colleague == colleagueB){ if(mess.length >= 2){ colleagueA.receiverMess(colleague.getName()+mess[0]); colleagueC.receiverMess(colleague.getName()+mess[1]); } } if(colleague == colleagueC){ if(mess.length >= 2){ colleagueA.receiverMess(colleague.getName()+mess[0]); colleagueB.receiverMess(colleague.getName()+mess[1]); } } } }
(3)具体同事(ConcreteColleague)
对于本问题。有ColleagueA、ColleagueB和ColleagueC三个具体同事,其实例分别表示交战的三方,代码如下:
ColleagueA.java
package com.liuzhen.nine_mediator; public class ColleagueA implements Colleague { ConcreteMediator mediator; //中介者 String name; ColleagueA(ConcreteMediator mediator){ this.mediator = mediator; mediator.registerColleagueA(this); } public void giveMess(String[] mess) { // TODO Auto-generated method stub mediator.deliveMess(this, mess); } public void receiverMess(String mess) { // TODO Auto-generated method stub System.out.println(name+"收到的消息:"); System.out.println("\t"+mess); } public void setName(String name) { // TODO Auto-generated method stub this.name = name; } public String getName() { // TODO Auto-generated method stub return name; } }
ColleagueB.java
package com.liuzhen.nine_mediator; public class ColleagueB implements Colleague { ConcreteMediator mediator; //中介者 String name; ColleagueB(ConcreteMediator mediator){ this.mediator = mediator; mediator.registerColleagueB(this); } public void giveMess(String[] mess) { // TODO Auto-generated method stub mediator.deliveMess(this, mess); } public void receiverMess(String mess) { // TODO Auto-generated method stub System.out.println(name+"收到的消息:"); System.out.println("\t"+mess); } public void setName(String name) { // TODO Auto-generated method stub this.name = name; } public String getName() { // TODO Auto-generated method stub return name; } }
ColleagueC.java
package com.liuzhen.nine_mediator; public class ColleagueC implements Colleague { ConcreteMediator mediator; //中介者 String name; ColleagueC(ConcreteMediator mediator){ this.mediator = mediator; mediator.registerColleagueC(this); } public void giveMess(String[] mess) { // TODO Auto-generated method stub mediator.deliveMess(this, mess); } public void receiverMess(String mess) { // TODO Auto-generated method stub System.out.println(name+"收到的消息:"); System.out.println("\t"+mess); } public void setName(String name) { // TODO Auto-generated method stub this.name = name; } public String getName() { // TODO Auto-generated method stub return name; } }
(4)具体使用
通过NineApplication类来具体实现上述相关类和接口,来实现适配器模式的运用,其代码如下:
package com.liuzhen.nine_mediator; public class NineApplication { public static void main(String[] args){ ConcreteMediator mediator = new ConcreteMediator(); ColleagueA colleagueA = new ColleagueA(mediator); ColleagueB colleagueB = new ColleagueB(mediator); ColleagueC colleagueC = new ColleagueC(mediator); colleagueA.setName("A国"); colleagueB.setName("B国"); colleagueC.setName("C国"); String[] messA = {"要求B方归还曾抢夺的100斤土豆" , "要求C方归还曾抢夺的20头牛"}; colleagueA.giveMess(messA); String[] messB = {"要求A方归还曾抢夺的10只公鸡" , "要求C方归还曾抢夺的15匹马"}; colleagueB.giveMess(messB); String[] messC = {"要求A方曾抢夺的360斤小麦" , "要求B方曾抢夺的50头驴"}; colleagueC.giveMess(messC); } }
运行结果:
B国收到的消息:
A国要求B方归还曾抢夺的100斤土豆
C国收到的消息:
A国要求C方归还曾抢夺的20头牛
A国收到的消息:
B国要求A方归还曾抢夺的10只公鸡
C国收到的消息:
B国要求C方归还曾抢夺的15匹马
A国收到的消息:
C国要求A方曾抢夺的360斤小麦
B国收到的消息:
C国要求B方曾抢夺的50头驴
相关推荐
行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式) 2) 学习目标:通过学习,学员...
JavaScript常见的一些设计模式学习笔记和代码实现。包括工厂模式、单例模式、代理模式、发布订阅模式、中介者模式等等内容。
3. 行为型模式:行为型模式关注对象之间的通信和协作,包括责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。这些模式可以帮助...
主要为大家详细介绍了javascript设计模式之中介者模式学习笔记,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
Java Design PatternsJava 设计模式学习笔记,简单易懂,每个模式都有相应的代码示列,帮助学习理解。在线阅读地址:设计原则创建型模式作用:将创建与使用代码解耦结构型模式作用:将不同的功能代码解耦桥接模式...
describe:设计模式学习笔记 逻辑结构图 代码结构图 设计模式简述 创建型模式,共五种:工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式,共七种:适配器模式,装饰器模式,代理模式,...
中介者模式 备忘录模式 迭代器模式 解释器模式 :collision:数据结构与算法 点击关闭/打开所有内容 :comet:源码学习 博客 :ant:数据结构与算法 :spider:设计模式 :honeybee:Javascript 语言标准 函数式编程 :...
第一部分:设计模式 & UML 简单工厂 工厂方法模式 抽象工厂模式 策略模式 责任链模式 命令模式 模板方法模式 适配器模式 代理模式 外观模式 组合模式 装饰模式 享元模式 桥接模式 Builder模式 状态模式 解释器模式 ...
中介者模式 组合模式 装饰模式 享元模式 桥接模式 ##第二部分 ##第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 ##第四部分 ##第五部分 ##第六...
中介者模式 组合模式 装饰模式 享元模式 桥接模式 第二部分 第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 第四部分 第五部分 第六部分 有任何...
中介者模式 组合模式 装饰模式 享元模式 桥接模式 第二部分 第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 第四部分 第五部分 第六部分 有任何...
VS2005 ASP.NET本地化学习笔记&感受 在自定义Server Control中捆绑JS文件 Step by Step 深度解析Asp.Net2.0中的Callback机制 使用 Web 标准生成 ASP.NET 2.0 Web 站点 ASP.NET 2.0基于SQLSERVER 2005的aspnetdb.mdf...
Java Design Patterns 学习笔记 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元...
中介者模式 组合模式 装饰模式 享元模式 桥接模式 第二部分 第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 第四部分 第五部分 第六部分 有任何...
study-notes个人学习笔记目录JavaScriptCSSHTML碎片知识点lifecircleReact虚拟DOMJSXbuild-your-own-reactHTTPHttp 协议跨域HTTPSTCP/IP资源缓存js设计模式策略模式中介者模式单例模式观察者模式发布订阅模式数据...
中介者模式 组合模式 装饰模式 享元模式 桥接模式 ##第二部分 ##第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 ##第四部分 ##第五部分 ##第六...
中介者模式 组合模式 装饰模式 享元模式 桥接模式 ##第二部分 ##第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 ##第四部分 ##第五部分 ##第六...