定义

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

试想一下,如果多个类之间相互都有引用,那么当其中一个类修改时,势必导致所有相关联的类都需要修改,如果引入一个中介类来管理所有类的交互,即所有类都通过中介类和其它类交互,则可以大大降低多个类之间的耦合;中介对象主要是用来封装行为的,行为的参与者就是那些对象,但是通过中介者,这些对象不用相互知道。

UML

优点

  1. 降低了系统对象之间的耦合性,使得对象易于独立的被复用;
  2. 提高系统的灵活性,使得系统易于扩展和维护;
  3. 可以让对象之间传递的消息变得简单而且大幅减少。

缺点

  1. 如果设计不当,中介者对象本身会变得过于复杂;
  2. 因为中介承担了较多的责任,所以一旦这个中介对象出现了问题,那么整个系统就会受到重大的影响。

应用场景

  1. 一组定义良好的对象,现在要进行复杂的通信。
  2. 定制一个分布在多个类中的行为,而又不想生成太多的子类。

示例

考虑一种简单的情况只有两个类A和B,类中各有一个数字,并且要保证类B中的数字永远是类A中数字的100倍。也就是说,当修改类A的数时,将这个数字乘以100赋给类B,而修改类B时,要将数除以100赋给类A。

Java

 public class Main
{
public static void main(String[] args)
{
AbstractColleague collA = new ColleagueA();
AbstractColleague collB = new ColleagueB(); AbstractMediator am = new Mediator(collA, collB); System.out.println("==========通过设置A影响B==========");
collA.setNumber(1000, am);
System.out.println("collA的number值为:" + collA.getNumber());
System.out.println("collB的number值为A的100倍:" + collB.getNumber()); System.out.println("==========通过设置B影响A==========");
collB.setNumber(1000, am);
System.out.println("collB的number值为:" + collB.getNumber());
System.out.println("collA的number值为B的0.01倍:" + collA.getNumber());
} /**
* 中介类基类
*/
public static abstract class AbstractMediator
{
protected AbstractColleague A;
protected AbstractColleague B; public AbstractMediator(AbstractColleague a, AbstractColleague b)
{
A = a;
B = b;
} public abstract void AaffectB(); public abstract void BaffectA();
} /**
* 同事类基类
*/
public static abstract class AbstractColleague
{
protected int number; public int getNumber()
{
return number;
} public void setNumber(int number)
{
this.number = number;
} //注意这里的参数不再是同事类,而是一个中介者
public abstract void setNumber(int number, AbstractMediator am);
} /**
* 同事类A
*/
public static class ColleagueA extends AbstractColleague
{ public void setNumber(int number, AbstractMediator am)
{
this.number = number;
am.AaffectB();
}
} /**
* 同事类B
*/
public static class ColleagueB extends AbstractColleague
{
@Override
public void setNumber(int number, AbstractMediator am)
{
this.number = number;
am.BaffectA();
}
} /**
* 中介实现类
*/
public static class Mediator extends AbstractMediator
{
public Mediator(AbstractColleague a, AbstractColleague b)
{
super(a, b);
} //处理A对B的影响
public void AaffectB()
{
int number = A.getNumber();
B.setNumber(number * 100);
} //处理B对A的影响
public void BaffectA()
{
int number = B.getNumber();
A.setNumber(number / 100);
}
}
}

行为类模式(五):中介者(Mediator)的更多相关文章

  1. 行为型模式(五) 中介者模式(Mediator)

    一.动机(Motivate) 为什么要使用中介者模式呢?如果不使用中介者模式的话,各个同事对象将会相互进行引用,如果每个对象都与多个对象进行交互时,将会形成如下图所示的网状结构.从上图可以发现,如果不 ...

  2. GoF23种设计模式之行为型模式之中介者模式

    一.概述 使用一个中介对象来封装一系列的对象交互.中介者让各个对象无需显式地相互引用,从而达到解耦的效果.并且可以独立地改变它们之间的交互.二.适用性1.当一组对象以定义良好但复杂通信的时候.产生的相 ...

  3. 【转】设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)

    设计模式 ( 十五 ) 中介者模式Mediator(对象行为型) 1.概述 在面向对象的软件设计与开发过程中,根据"单一职责原则",我们应该尽量将对象细化,使其只负责或呈现单一的职 ...

  4. 设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)

    设计模式 ( 十五 ) 中介者模式Mediator(对象行为型) 1.概述 在面向对象的软件设计与开发过程中,根据“单一职责原则”,我们应该尽量将对象细化,使其只负责或呈现单一的职责,即将行为分布到各 ...

  5. 设计模式---接口隔离模式之中介者模式(Mediator)

    一:概念 在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互.Mediator对象起到控制器的作用 二:动机 在软件构建的过程中, ...

  6. 重构if...else...或者switch程序块 为 中介者(Mediator)模式.的思考

    http://www.cnblogs.com/insus/p/4142264.html 重构if...else...或者switch程序块 为 中介者(Mediator)模式.的思考 首先普世的编程架 ...

  7. Java进阶篇设计模式之十 ---- 访问者模式和中介者模式

    前言 在上一篇中我们学习了行为型模式的解释器模式(Interpreter Pattern)和迭代器模式(Iterator Pattern).本篇则来学习下行为型模式的两个模式,访问者模式(Visito ...

  8. Java设计模式之十 ---- 访问者模式和中介者模式

    前言 2018年已经过去,新的一年工作已经开始,继续总结和学习Java设计模式. 在上一篇中我们学习了行为型模式的解释器模式(Interpreter Pattern)和迭代器模式(Iterator P ...

  9. 轻松掌握:JavaScript代理模式、中介者模式

    代理模式.中介者模式 代理模式 在面向对象设计中,有一个单一职责原则,指就一个类(对象.函数)而言,应该仅有一个引起它变化的原因.如果一个对象承担了过多的职责,就意味着它将变得巨大,引起它变化的原因就 ...

随机推荐

  1. django之创建第10个项目-图片上传方式1

    1.upload.HTMl <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang=& ...

  2. Libevent官方代码样例学习(一)

    在Ubuntu16.04中, libevent的默认安装位置为 #在 trusty 发行版中 amd64 硬件架构下的 libevent- 软件包文件清单 /usr/lib/x86_64-linux- ...

  3. Linux中svn的使用

    1. 安装Linux 执行如下命令,中间会出现一次提示,选y即可 yum install subversion 2. 创建资源库位置 svnadmin create /usr/java/testJen ...

  4. c++ 11 override final

    C++ 11添加了两个继承控制关键字:override和final. override确保在派生类中声明的重载函数跟基类的虚函数有相同的签名.final阻止类的进一步派生和虚函数的进一步重载

  5. 什么是EPEL 及 Centos上安装EPEL

    RHEL以及他的衍生发行版如CentOS为了稳定,官方的rpm repository提供的rpm包为了服务器安全稳定更新往往是很滞后的,很多时候需要自己编译那太辛苦了,而EPEL恰恰可以解决这两方面的 ...

  6. saltstack 基础入门文档

    saltstack 和 Puppet Chef 一样可以让你同时在多台服务器上执行命令也包括安装和配置软件.Salt 有两个主要的功能:配置管理和远程执行.这里讲述了saltstack的基本使用方法. ...

  7. 信号之sigsetjmp和siglongjmp函数(转)

    在信号处理程序中经常调用longjmp函数以返回到程序的主循环中,而不是从该处理程序返回. 但是,调用longjmp有一个问题.当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被自动地加到进程的信号 ...

  8. 一台电脑存放多个git账户的多个rsa秘钥(转)

    如何在一个电脑上存储多个git账户生成的多份rsa秘钥,实现多个账户同时使用配置的情况?今天,不幸又再次遇到这个问题. 问题描述 公司最近在开发一款开源产品,项目被托管在github上,但是公司内部一 ...

  9. 超高频RFID模块

    1.应用开发有两种方法:串口和USB 2.从逻辑上将标签存储器分为四个存储区,每个存储区可以由一个或一个以上的存储器字组成.这四个存储区是: 00 保留区(Password):前两个字是销毁(kill ...

  10. Android----Thread+Handler 线程 消息循环(转载)

    近来找了一些关于android线程间通信的资料,整理学习了一下,并制作了一个简单的例子. andriod提供了 Handler 和 Looper 来满足线程间的通信.例如一个子线程从网络上下载了一副图 ...