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 stubmediator.deliveMess(this, mess);}public void receiverMess(String mess) {// TODO Auto-generated method stubSystem.out.println(name+"收到的消息:");System.out.println("\t"+mess);}public void setName(String name) {// TODO Auto-generated method stubthis.name = name;}public String getName() {// TODO Auto-generated method stubreturn 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 stubmediator.deliveMess(this, mess);}public void receiverMess(String mess) {// TODO Auto-generated method stubSystem.out.println(name+"收到的消息:");System.out.println("\t"+mess);}public void setName(String name) {// TODO Auto-generated method stubthis.name = name;}public String getName() {// TODO Auto-generated method stubreturn 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 stubmediator.deliveMess(this, mess);}public void receiverMess(String mess) {// TODO Auto-generated method stubSystem.out.println(name+"收到的消息:");System.out.println("\t"+mess);}public void setName(String name) {// TODO Auto-generated method stubthis.name = name;}public String getName() {// TODO Auto-generated method stubreturn 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头驴

参考资料:

      1.Java设计模式/耿祥义,张跃平著.——北京:清华大学出版社,2009.5

转载于:https://www.cnblogs.com/liuzhen1995/p/5996792.html

设计模式学习笔记(九:中介者模式)相关推荐

  1. 设计模式学习笔记--Mediator 中介者模式

    我们知道面向对象应用程序是由一组为了提供某种服务而彼此交互的对象组成.当彼此引用的对象数量比较少时,此时对象之间就为直接交互(点对点).而当对象的数量增加时,这种直接交互会导致对象之间复杂的.混乱的引 ...

  2. 设计模式学习笔记九:原型模式(Prototype Pattern)

    1.概述     意图:我们将已经存在的对象作为原型,用户可以通过复制这些原型创建新的对象.     使用场合:当一个系统应该独立于产品的创建.构造和表示时,可以使用原型模式.在原型模式中,产品的创建 ...

  3. 设计模式学习笔记——享元(Flyweight)模式

    设计模式学习笔记--享元(Flyweight)模式 @(设计模式)[设计模式, 享元模式, flyweight] 设计模式学习笔记享元Flyweight模式 基本介绍 享元案例 类图 实现代码 Big ...

  4. 设计模式学习笔记——单例(Singleton)模式

    设计模式学习笔记--单例(Singleton)模式 @(设计模式)[设计模式, 单例模式, Singleton, 懒汉式, 饿汉式] 设计模式学习笔记单例Singleton模式 基本介绍 单例案例 类 ...

  5. 设计模式学习笔记--Flyweight享元模式

    Flyweight模式也叫享元模式,是由GoF提出的23种设计模式中的一种.Flyweight模式是构造型模式之一,它通过与其他类似对象共享数据来减小内存占用,所以叫享元.   此模式解决的是由于大量 ...

  6. 设计模式学习笔记--享元(Flyweight)模式

    写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式:每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案:当我们碰到模式 ...

  7. 步步为营 .NET 设计模式学习笔记 九、Command(命令模式)

    概述 在软件系统中,"行为请求者"与"行为实现者"通常呈现一种"紧耦合".但在某些场合,比如要对行为进行"记录.撤销/重做.事务& ...

  8. C#设计模式学习笔记:(4)建造者模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7614630.html,记录一下学习过程以备后续查用.一.引言在现实生活中,我们经常会遇到一些构成比较复杂的物 ...

  9. 设计模式学习笔记(八)—Template Method模式

    factory模式(包括简单工厂和抽象工厂),Strategy模式,Template method模式是学习Spring框架必不可少的. <设计模式>一书对Template Method模 ...

  10. 设计模式学习笔记(一)之工厂模式、单例模式

    一.工厂模式 (1)简单工厂模式: 1 public interface IProduct { 2 3 public void saleProduct(); 4 5 } 创建一个产品接口,有一个卖产品 ...

最新文章

  1. Python3中装饰器@typing.overload的使用
  2. 速卖通爆款如何打造,爆款的周期有多久?
  3. 用c语言实现对n个进程采用“短进程优先”算法的进程调度_为什么Linux CFS调度器没有带来惊艳的碾压效果?...
  4. OpenGL Indirect Culling间接剔除实例
  5. inline修饰虚函数问题
  6. django不修改数据库创外键_Django——model(建表,增删改查,外键,多对多)
  7. Android官方开发文档Training系列课程中文版:构建第一款安卓应用之创建用户界面
  8. 吴恩达深度学习4.2练习_Convolutional Neural Networks_Residual Networks
  9. 架构之重构的12条军规
  10. [转载] Java中使用new构造数组时会不会自动调用类的默认构造函数
  11. Linux kali 安装 qq Tim
  12. 树莓派4B改装RC玩具车玩转opencv系列教程(一)树莓派基础入门篇------Hello Raspberry Pi OS(Rasbian )!
  13. 其他综合-fdisk一键分区操作-无需脚本
  14. 那些让我印象深刻的bug--04
  15. epub 免费转换网站
  16. composer 安装laravel 5.5 苹果终端
  17. 什么是机械学习?及Scikit-learn机械学习库
  18. 高等数学复习之六(微分方程)
  19. 关联规则挖掘算法: Aprior算法和Fpgrowth算法
  20. 2020年游戏年收入同比增幅游戏出口近千亿元规模

热门文章

  1. 手拉手教你实现一门编程语言 Enkel, 系列 15
  2. Revit二次开发: 文件损坏
  3. 巴塞罗那IoT“首秀”归来,新华三成功展现物联网风采
  4. SharedCache-共享缓存概况和初步运用实例(1)
  5. 使用 RESTful 的方式开发 Web应用
  6. 教你彻底禁止暴风影音后门进程自己启动
  7. 新手必读——OOP三大特征及联系
  8. HDU5234 Happy birthday
  9. 华为平板m5鸿蒙,华为平板M5系列发布:搭载麒麟960 售价2088元起
  10. php往pdf模板添加数据,php实现往pdf中加数字签名操作示例【附源码下载】