一、定义

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

二、结构

组成:

  ● 抽象中介者(Mediator)角色:定义统一的接口用于各同事角色之间的通信,其中主要方法是一个(或多个)事件方法。

  ● 具体中介者(ConcreteMediator)角色:实现了抽象中介者所声明的事件方法。具体中介者知晓所有的具体同事类,并负责具体的协调各同事对象的交互关系。

  ● 抽象同事类(Colleague)角色:定义出中介者到同事角色的接口。同事角色只知道中介者而不知道其余的同事角色。与其他的同事角色通信的时候,一定要通过中介者角色协作。

  ● 具体同事类(ConcreteColleague)角色:所有的具体同事类均从抽象同事类继承而来。实现自己的业务,在需要与其他同事通信的时候,就与持有的中介者通信,中介者会负责与其他的同事交互。

代码结构

 //抽象中介者类
public interface IMediator
{
/**
* 同事对象在自身改变的时候来通知中介者的方法
* 让中介者去负责相应的与其他同事对象的交互
*/
void Changed(Colleague c);
} //抽象同事类
public abstract class Colleague
{
//持有一个中介者对象
private IMediator _mediator;
/**
* 构造函数
*/
public Colleague(IMediator mediator)
{
this._mediator = mediator;
}
/**
* 获取当前同事类对应的中介者对象
*/
public IMediator GetMediator()
{
return _mediator;
}
} //具体中介者类
public class ConcreteMediator : IMediator
{
//持有并维护同事A
private ConcreteColleagueA _colleagueA;
//持有并维护同事B
private ConcreteColleagueB _colleagueB; public void SetColleagueA(ConcreteColleagueA colleagueA)
{
this._colleagueA = colleagueA;
} public void SetColleagueB(ConcreteColleagueB colleagueB)
{
this._colleagueB = colleagueB;
} public void Changed(Colleague c)
{
/**
* 某一个同事类发生了变化,通常需要与其他同事交互
* 具体协调相应的同事对象来实现协作行为
*/
}
} //具体同事类
public class ConcreteColleagueA : Colleague
{ public ConcreteColleagueA(IMediator mediator) : base(mediator)
{
}
/**
* 示意方法,执行某些操作
*/
public void Operation()
{
//在需要跟其他同事通信的时候,通知中介者对象
GetMediator().Changed(this);
}
}
public class ConcreteColleagueB : Colleague
{ public ConcreteColleagueB(IMediator mediator) : base(mediator)
{
}
/**
* 示意方法,执行某些操作
*/
public void Operation()
{
//在需要跟其他同事通信的时候,通知中介者对象
GetMediator().Changed(this);
}
}

三、适用场景

1、系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。

2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

应用实例

1、中国加入 WTO 之前是各个国家相互贸易,结构复杂,现在是各个国家通过 WTO 来互相贸易。

2、机场调度系统。

3、MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。

四、优缺点

  优点: 1、降低了类的复杂度,将一对多转化成了一对一。 2、各个类之间的解耦。 3、符合迪米特原则。

  缺点:中介者会庞大,变得复杂难以维护。

五、实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DesignPatterns.Mediator
{
class Program
{
static void Main(string[] args)
{
MessageMediator mediator = new MessageMediator(); ConcreteColleagueA a = new ConcreteColleagueA(mediator, "A");
ConcreteColleagueB b = new ConcreteColleagueB(mediator, "B");
ConcreteColleagueC c = new ConcreteColleagueC(mediator, "C"); mediator.SetColleagueA(a);
mediator.SetColleagueB(b);
mediator.SetColleagueC(c); mediator.Chat(a, "中午吃啥饭?");
Console.WriteLine("===="); mediator.Chat(b, "我想吃刀削面");
Console.WriteLine("===="); mediator.Chat(c, "我也想吃刀削面");
Console.WriteLine("===="); mediator.Chat(a, "行,那中午一起去吃刀削面吧");
}
} //抽象中介者类
public interface IMediator
{
void Chat(Colleague c, string message);
} //抽象同事类
public abstract class Colleague
{
private string name;
//持有一个中介者对象
private IMediator _mediator; public Colleague(IMediator mediator, string name)
{
this._mediator = mediator;
this.name = name;
}
/**
* 获取当前同事类对应的中介者对象
*/
public IMediator GetMediator()
{
return _mediator;
} /**
* 获取昵称
*/
public string getName()
{
return name;
} /**
* 接收消息
*/
public abstract void receive(string message); /**
* 发送消息
*/
public abstract void send(string message);
} //具体中介者类
public class MessageMediator : IMediator
{
//持有并维护同事A
private ConcreteColleagueA _colleagueA;
//持有并维护同事B
private ConcreteColleagueB _colleagueB; private ConcreteColleagueC _colleagueC; public void SetColleagueA(ConcreteColleagueA colleagueA)
{
this._colleagueA = colleagueA;
} public void SetColleagueB(ConcreteColleagueB colleagueB)
{
this._colleagueB = colleagueB;
}
public void SetColleagueC(ConcreteColleagueC colleagueC)
{
this._colleagueC = colleagueC;
} public void Chat(Colleague c, string message)
{
if (_colleagueA != null)
{
_colleagueA.send(message);
_colleagueB.receive(message);
_colleagueC.receive(message);
}
else if (_colleagueB != null) {
_colleagueB.send(message);
_colleagueA.receive(message);
_colleagueC.receive(message);
} else if (_colleagueC != null) {
_colleagueC.send(message);
_colleagueA.receive(message);
_colleagueB.receive(message);
}
}
} //具体同事类
public class ConcreteColleagueA : Colleague
{ public ConcreteColleagueA(IMediator mediator, string name) : base(mediator, name)
{
}
/**
* 示意方法,执行某些操作
*/
public void Operation(string message)
{
//在需要跟其他同事通信的时候,通知中介者对象
GetMediator().Chat(this, message);
} public override void receive(String message)
{
Console.WriteLine("【A】收到消息:【" + message + "】");
} public override void send(String message)
{
Console.WriteLine("【A】发出消息:【" + message + "】");
}
}
public class ConcreteColleagueB : Colleague
{ public ConcreteColleagueB(IMediator mediator, string name) : base(mediator, name)
{
}
/**
* 示意方法,执行某些操作
*/
public void Operation(string message)
{
//在需要跟其他同事通信的时候,通知中介者对象
GetMediator().Chat(this, message);
} public override void receive(String message)
{
Console.WriteLine("【B】收到消息:【" + message + "】");
} public override void send(String message)
{
Console.WriteLine("【B】发出消息:【" + message + "】");
}
} public class ConcreteColleagueC : Colleague
{ public ConcreteColleagueC(IMediator mediator, string name) : base(mediator, name)
{
}
/**
* 示意方法,执行某些操作
*/
public void Operation(string message)
{
//在需要跟其他同事通信的时候,通知中介者对象
GetMediator().Chat(this, message);
} public override void receive(String message)
{
Console.WriteLine("【C】收到消息:【" + message + "】");
} public override void send(String message)
{
Console.WriteLine("【C】发出消息:【" + message + "】");
}
}
}

结果

【A】发出消息:【中午吃啥饭?】
【B】收到消息:【中午吃啥饭?】
【C】收到消息:【中午吃啥饭?】
====
【A】发出消息:【我想吃刀削面】
【B】收到消息:【我想吃刀削面】
【C】收到消息:【我想吃刀削面】
====
【A】发出消息:【我也想吃刀削面】
【B】收到消息:【我也想吃刀削面】
【C】收到消息:【我也想吃刀削面】
====
【A】发出消息:【行,那中午一起去吃刀削面吧】
【B】收到消息:【行,那中午一起去吃刀削面吧】
【C】收到消息:【行,那中午一起去吃刀削面吧】

参考:

http://www.cnblogs.com/JsonShare/p/7263876.html

http://www.runoob.com/design-pattern/mediator-pattern.html

欢迎阅读本系列文章:Head First设计模式之目录

Head First设计模式之中介者模式的更多相关文章

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

    原文:乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:weba ...

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

    博文原址:折腾Java设计模式之中介者模式 中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并 ...

  3. js设计模式——8.中介者模式

    js设计模式——8.中介者模式 /*js设计模式——中介者模式*/ class A { constructor() { this.number = 0; } setNumber(num, m) { t ...

  4. 【GOF23设计模式】中介者模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_中介者模式.同事协作类.内部类实现 package com.test.mediator; /** * 同事类的接口 */ ...

  5. [设计模式] 17 中介者模式 Mediator Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对中介者模式是这样说的:用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变 ...

  6. 再起航,我的学习笔记之JavaScript设计模式23(中介者模式)

    中介者模式 概念介绍 中介者模式(Mediator):通过中介者对象封装一系列对象之间的交互,使对象之间不再相互引用降低他们之间的耦合,有时中介者对象也可以改变对象之间的交互. 创建一个中介 中介者模 ...

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

    中介者模式是关于数据交互的设计模式,该模式的核心是一个中介者对象,负责协调一系列对象之间的不同的数据请求,这一系列对象成为同事类.如房产中介(简直不想提它),买房的卖房的,租房的放租的都到房产中介那里 ...

  8. PHP设计模式系列 - 中介者模式

    中介者模式 中介者模式用于开发一个对象,这个对象能够在类似对象相互之间不直接相互的情况下传送或者调解对这些对象的集合的修改.一般处理具有类似属性,需要保持同步的非耦合对象时,最佳的做法就是中介者模式. ...

  9. 深入理解JavaScript系列(36):设计模式之中介者模式

    介绍 中介者模式(Mediator),用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 主要内容来自:http://www ...

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

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

随机推荐

  1. Common Data Service (CDS) 初探

    作者:陈希章 发表于 2017年12月16日 前言 Common Data Service(以下简称为CDS),通用数据服务是一个创新性的基础功能,这是微软试图打造一个全新的基于SaaS模式的数据服务 ...

  2. 采用Opserver来监控你的ASP.NET项目系列(二、监控SQL Server与Asp.Net项目)

    前言 之前有过2篇关于如何监控ASP.NET core项目的文章,有兴趣的也可以看看. 今天我们主要来介绍一下,如何使用Opserver监控我们的SQL Server 和ASP.NET项目的异常监控 ...

  3. 使用python处理excle表格

    # -*- coding: utf-8 -*- import xlrd ########################### #通用功能,读取excel表格中所有数据 #返回一个包含所有单元格名和对 ...

  4. tomcat8权限分离

    安装jdk tar xf jdk-8u121-linux-x64.tar.gz mv jdk-*  /usr/local/jdk1.8 vi /etc/profile export JAVA_HOME ...

  5. 【Hdu3555】 Bomb(数位DP)

    Description 题意就是找0到N有多少个数中含有49. \(1\leq N \leq2^{63}-1\) Solution 数位DP,与hdu3652类似 \(F[i][state]\)表示位 ...

  6. Automatic Preferred Max Layout Width is not available on iOS versions prior to

    警告:Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0 如: 找到: : 改动为:

  7. 在线安装eclipse中html/jsp/xml editor插件(很可靠)

    之前有一篇文章也是安装eclipse中的web开发插件 ,可是经过非常多人使用,那种方法.不是全部人使用都能够. 接下来,找到一种很管用的方法.就是在线安装. 废话不多说,这样的方法绝对能够成功安装. ...

  8. python集合增删改查,深拷贝浅拷贝

    集合 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 去重,把一个列表变成集合,就自动去重了. 关系 ...

  9. Laravel学习笔记(三)--在CentOS上配置Laravel

    在Laravel框架上开发了几天,不得不说,确实比较优雅,处理问题逻辑比较清楚.     今天打算在CentOS 7上配置一个Laravel,之前都是在本机上开发,打算实际配置一下.     1)系统 ...

  10. 给虚拟机添加新硬盘并分区,fdisk查看分区,分区,重新读取分区表信息partprobe,格式化,挂载,查看分区挂载信息,自动挂载文件/etc/fstab,/etc/fstab文件错误导致重启崩溃后的修复

    1.虚拟机关机断电 2.添加硬盘 2.开机 3.fdisk -l查看刚才新添加的硬盘 [root@localhost ~]# fdisk -l 磁盘 /dev/sda:21.5 GB, 2147483 ...