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

组成:
● 抽象中介者(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设计模式之中介者模式的更多相关文章
- 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)
原文:乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:weba ...
- 折腾Java设计模式之中介者模式
博文原址:折腾Java设计模式之中介者模式 中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并 ...
- js设计模式——8.中介者模式
js设计模式——8.中介者模式 /*js设计模式——中介者模式*/ class A { constructor() { this.number = 0; } setNumber(num, m) { t ...
- 【GOF23设计模式】中介者模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_中介者模式.同事协作类.内部类实现 package com.test.mediator; /** * 同事类的接口 */ ...
- [设计模式] 17 中介者模式 Mediator Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对中介者模式是这样说的:用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变 ...
- 再起航,我的学习笔记之JavaScript设计模式23(中介者模式)
中介者模式 概念介绍 中介者模式(Mediator):通过中介者对象封装一系列对象之间的交互,使对象之间不再相互引用降低他们之间的耦合,有时中介者对象也可以改变对象之间的交互. 创建一个中介 中介者模 ...
- 设计模式之中介者模式(Mediator )
中介者模式是关于数据交互的设计模式,该模式的核心是一个中介者对象,负责协调一系列对象之间的不同的数据请求,这一系列对象成为同事类.如房产中介(简直不想提它),买房的卖房的,租房的放租的都到房产中介那里 ...
- PHP设计模式系列 - 中介者模式
中介者模式 中介者模式用于开发一个对象,这个对象能够在类似对象相互之间不直接相互的情况下传送或者调解对这些对象的集合的修改.一般处理具有类似属性,需要保持同步的非耦合对象时,最佳的做法就是中介者模式. ...
- 深入理解JavaScript系列(36):设计模式之中介者模式
介绍 中介者模式(Mediator),用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 主要内容来自:http://www ...
- Java 设计模式之中介者模式
本文继续23种设计模式系列之中介者模式. 定义 用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互. 角色 抽象中介者: ...
随机推荐
- 实战-Mysql主从复制
前言: Mysql内建的复制功能是构建大型高性能应用程序的基础.由于目前mysql的高可用性架构MMM和MHA均建立在复制的基础之上,本文就mysql主从复制进行实战描述,希望对读者提供帮助.之前 服 ...
- Git命令汇总(补充篇)
上一篇<Git命令汇总基础篇>总结了使用Git的基本命令,这一篇作为补充主要给大家讲一些平时使用中的技巧和总结 . 学会了这些命令,已经基本解决了使用Git中大部分问题. 1.gitign ...
- 使用PowerApps快速构建基于主题的轻业务应用 —— 入门篇
作者:陈希章 发表于 2017年12月12日 前言 在上一篇文章 基于Office 365的随需应变业务应用平台 中我提到,随着随需应变的业务需要,以及技术的发展,业务应用的开发的模式也有了深刻的变化 ...
- C language 模拟 win的经典游戏——扫雷
让我们在terminal下愉快的...扫雷 昨天跟奇葩霖聊起"雷区"这个敏感词汇,然后非常荣幸的... 应该轰炸不到我.. . 后来百无聊赖的去玩了把扫雷.然后发现我之前都是乱扫的 ...
- linux 开机批量启动程序
每天早上到公司第一件事打开电脑,打开我的qq.我的开发工具idea.在看看邮件,日复一日,变懒了.也变聪明了,写了以下一段脚本 文件名称:mystart.sh #!bin/bash #检验我的开发工具 ...
- Zend_Json 简介 --(手冊)
1. 简单介绍 Zend_Json 提供一个方便的方式来串联(native的)PHP(的变量)和JSON,并将JSON(对象)解码到PHP中. 2. 基本使用方法 Zend_Json的使用包含使用 ...
- git入门(msysgit安装)
1.下载git-for-windows 常用的GitHub客户端msysgit,也就是git-for-windows. 登录官网 https://git-for-windows.github.io/, ...
- Jenkins+github+maven+git+linux
Jenkins:持续集成的一个工具 github:远程存放代码 maven:利用maven创建项目,配置pom.xm依赖 git :本地仓库,可以提交代码到远程(我都是使用git 在git bush ...
- 'boost/iterator/iterator_adaptor.hpp' file not found之xcode生成时报错的解决方案
xcode生成rn(0.49.3)项目的时候出现“'boost/iterator/iterator_adaptor.hpp' file not found之xcode”报错. 原因: /Users/x ...
- [置顶]
Xamarin android如何调用百度地图入门示例(一)
在Xamarin android如何调用百度地图呢? 首先我们要区分清楚,百度地图这是一个广泛的概念,很多刚刚接触这个名词"百度地图api",的确是泛泛而谈,我们来看一下百度地图的 ...