意图

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

适用性

  • 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
  • 一个对象引用其他很多对象并且之间
  • 想定制一个分布在多个类中的行为,而又不想生成太多子类。

结构

实现

在未来的智能家居中,家里的各种电器相互关联,假设这样三种电器:闹钟,日历和咖啡壶。现在有这样两个任务:

  1. 当按下闹钟的“延迟”按钮(过5分钟后再次响铃)后,日历检查今天是否是星期日,如果不是,则咖啡壶开始准备咖啡。
  2. 当关闭日历,咖啡壶和闹钟也一同关闭。

同事类,每一个同事都知道他的中介者,当它需要与其他同事交流时,它只需通知中介者。

public abstract class Colleague
{
protected string _type;
protected Mediator _theMediator;
public string Type
{
get { return _type; }
}
public Mediator TheMediator
{
get { return _theMediator; }
set { _theMediator = value; }
}
}

具体同事

  public class Alarm : Colleague
{
public Alarm()
{
_type = "Alarm";
}
public void AlarmLater()
{
Console.WriteLine("Alarm 5min later");
_theMediator.Notify(this);
}
public void PowerOff()
{
Console.WriteLine("Alarm PowerOff");
}
}
public class CoffeePot : Colleague
{
public CoffeePot()
{
_type = "CoffeePot";
}
public void PrepareCoffee()
{
Console.WriteLine("Start preparing coffee");
}
public void PowerOff()
{
Console.WriteLine("CoffeePot PowerOff");
}
}
public class Calendar : Colleague
{
public Calendar()
{
_type = "Calendar";
}
public DayOfWeek GetDayOfWeek()
{
return DateTime.Today.DayOfWeek;
}
public void PowerOff()
{
Console.WriteLine("Calendar PowerOff");
_theMediator.Notify(this);
}
}

中介者定义一个用于与各同事通信的接口

  public  class Mediator
{
public virtual void Notify(Colleague colleague)
{
}
}

具体中介者了解和维护各个同事,并协调各同事以实现协作行为。

 public class FutureHouse : Mediator
{
private Alarm _alarm;
private CoffeePot _coffeePot;
private Calendar _calendar;
public Calendar HouseCalendar
{
get { return _calendar; }
set { _calendar = value; }
}
public CoffeePot HouseCoffeePot
{
get { return _coffeePot; }
set { _coffeePot = value; }
}
public Alarm HouseAlarm
{
get { return _alarm; }
set { _alarm = value; }
}
private void WeekUp()
{
if (HouseCalendar.GetDayOfWeek()!=DayOfWeek.Sunday)
{
HouseCoffeePot.PrepareCoffee();
}
}
private void PowerOff()
{
HouseCoffeePot.PowerOff();
HouseAlarm.PowerOff();
}
public override void Notify(Colleague colleague)
{
if (colleague.Type == "Alarm")
{
WeekUp();
}
else if (colleague.Type == "Calendar")
{
PowerOff();
}
}
}

使用

class Program
{
static void Main(string[] args)
{
var calendar = new Calendar();
var coffeePot = new CoffeePot();
var alarm = new Alarm();
var house = new FutureHouse();
calendar.TheMediator = house;
alarm.TheMediator = house;
coffeePot.TheMediator = house; house.HouseCalendar = calendar;
house.HouseAlarm = alarm;
house.HouseCoffeePot = coffeePot; alarm.AlarmLater(); calendar.PowerOff(); Console.ReadKey();
}
}

运行结果

  • 周日
  • 非周日

效果

  1. 减少了子类
  2. 将各Colleague解耦
  3. 简化了对象协议,使用Mediator和各Colleague间的一对多交互替代多对多交互
  4. 它对对象如何进行协助进行了抽象
  5. 使控制集中化
  6. 中介者可能变得庞大而且复杂,难以维护

参考

  1. 《Head First 设计模式》
  2. 《设计模式》

设计模式C#实现(十六)——中介者模式的更多相关文章

  1. javascript设计模式学习之十四——中介者模式

    一.中介者模式的定义和应用场景 中介者模式的作用在于解除对象之间的紧耦合关系,增加一个中介者之后,所有对象都通过中介者来通信,而不是互相引用,当一个对象发生变化的时候,仅需要通知中介者即可.从而将网状 ...

  2. [设计模式] 设计模式课程(十六)-- 备忘录模式(Memento)

    概述 也叫快照(SnapShot) 属于行为类设计模式 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态 软件构建过程中,某些对象的状态在转换过程中,可能由于某种需要,要求程序能回溯到对象之前 ...

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

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

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

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

  5. 模板方法模式 Template method 行为型 设计模式(二十六)

    模板方法模式 Template method 上图为网上百度的一份简历模板截图   相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为 ...

  6. Java 设计模式系列(十八)备忘录模式(Memento)

    Java 设计模式系列(十八)备忘录模式(Memento) 备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是对象的行为模式.备忘录对象是一个用来存储另外一个对象内部状态 ...

  7. Java 设计模式系列(十五)迭代器模式(Iterator)

    Java 设计模式系列(十五)迭代器模式(Iterator) 迭代器模式又叫游标(Cursor)模式,是对象的行为模式.迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象(interna ...

  8. Java 设计模式系列(十二)策略模式(Strategy)

    Java 设计模式系列(十二)策略模式(Strategy) 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以 ...

  9. Java 设计模式系列(十四)命令模式(Command)

    Java 设计模式系列(十四)命令模式(Command) 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复 ...

  10. Java 设计模式系列(十七)中介者模式

    Java 设计模式系列(十七)中介者模式 用一个中介对象来封装一系列的对象交互.中介者使得各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互 一.中介者模式结构 Media ...

随机推荐

  1. 【Android】直播必备之YUV使用总结 —— Android常用的几种格式:NV21/NV12/YV12/YUV420P的区别

    说明 因工作方面接触到图像处理这一块,需要对手机摄像头采集的原始帧做Rotate或者Scale,但无奈对此的了解少之又少,于是网上搜了一顿,完事后将最近所学总结一下,以方便之后的人别踩太多坑. 首先想 ...

  2. 让你分分钟学会Javascript中的闭包

    Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...

  3. Hexo主题实现多级分类显示

    前言 最近在搞一个博客,是托管在github和gitcafe上的,利用Hexo生成的.之后,发现一个问题,显示的分类都是一级的.而我想要的是:能显示多级分类,层次分明`的那样. 问题 基本主题自带的分 ...

  4. 关于log4net日志的配置流程

    最近又重新整理一下log4net日志的配置,现在记录一下流程和一些遇到的问题,以备后续使用,具体的配置参数等信息.此文无,见谅! 1. 下载log4net.dll文件(网上很多,随便找一个!) 2. ...

  5. 【原创】Silverlight DataGrid对核心控件DataGrid的任意单元格进行获取和设置分析。

    前几天,公司同事有个需求需要对系统中的DataGrid控件的指定单元格(如图,申请人ID)进行禁用设置,尝试了很多次总是 整行整列的 禁用 没实现效果. 网上资料较少,没找到解决措施. 尽管silve ...

  6. Javascript贪食蛇小游戏

    试玩:http://hovertree.com/game/9/ 贪吃蛇是一种风靡全球的小游戏,就是一条小蛇,不停地在屏幕上游走,吃各个方向出现的蛋,越吃越长.只要蛇头碰到屏幕四周,或者碰到自己的身子, ...

  7. C# 常用加密解密帮助类

    public static class EncryptUtil { #region MD5加密 /// <summary> /// MD5加密 /// </summary> p ...

  8. css遮罩代码(已验证)

    #mask { background-color: rgb(0, 0, 0); display:none; opacity: 0.0; /* Safari, Opera */ -moz-opacity ...

  9. 【linux草鞋应用编程系列】_5_ Linux网络编程

    一.网络通信简介   第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章.   二.linux网络通信     在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...

  10. java Io缓冲区复制文件

    //直接写代码了  类和包自己导入创建 ,手打很累的 public static void main(String args[]){ FileReader fr=null;   //文件输入流 Fil ...