设计模式--14、中介者模式

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

类型:行为类模式

看看结构图的形象描述吧:

中介者模式的结构

中介者模式又称为调停者模式,从类图中看,共分为3部分:

  • 抽象中介者:定义好同事类对象到中介者对象的接口,用于各个同事类之间的通信。一般包括一个或几个抽象的事件方法,并由子类去实现。
  • 中介者实现类:从抽象中介者继承而来,实现抽象中介者中定义的事件方法。从一个同事类接收消息,然后通过消息影响其他同时类。
  • 同事类:如果一个对象会影响其他的对象,同时也会被其他对象影响,那么这两个对象称为同事类。在类图中,同事类只有一个,这其实是现实的省略,在实际应用中,同事类一般由多个组成,他们之间相互影响,相互依赖。同事类越多,关系越复杂。并且,同事类也可以表现为继承了同一个抽象类的一组实现组成。在中介者模式中,同事类之间必须通过中介者才能进行消息传递。

为什么要使用中介者模式

一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如在下图中,有六个同事类对象,假如对象1发生变化,那么将会有4个对象受到影响。如果对象2发生变化,那么将会有5个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。

如果引入中介者模式,那么同事类之间的关系将变为星型结构,从图中可以看到,任何一个类的变动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。

对于设计模式这个东西,理解了,应该写一个代码体会一下,我们以qq和email发送消息为实例,代码如下:

package designpatterns;

import java.util.HashMap;
import java.util.Map.Entry;

/*
 * 中介者模式
 */
//先抽像一个使用者类(学生)
abstract class Person {
	String strName;	//姓名
	String strType;	//类型
	//每个人都有一个用来传递信息的中介List,如qq,email等
	HashMap<String, AbstractMediator> MyMediatorList = new HashMap<String, AbstractMediator>();
	public Person(String strName){
		this.strName = strName;
	}
	public String getStrName() {
		return strName;
	}
	public void setStrName(String strName) {
		this.strName = strName;
	}
	public String getStrType() {
		return strType;
	}
	public void setStrType(String strType) {
		this.strType = strType;
	}
	public void AddMediator(AbstractMediator MyMediator) {
		MyMediatorList.put(MyMediator.getStrName(), MyMediator);
	}
	//给所有人发消息
	public void SendMessageToAll(String MediatorName, String strMessage){
		MyMediatorList.get(MediatorName).SendMessageToAll(strMessage);
	}
	//给指定类型的人发消息
	public void SendMessageByType(String MediatorName, String strType, String strMessage) {
		MyMediatorList.get(MediatorName).SendMessageByType(strType, strMessage);
	}
	//给指定名字的人发消息
	public void SendMessageByName(String MediatorName, String strName, String strMessage) {
		MyMediatorList.get(MediatorName).SendMessageByName(strName, strMessage);
	}
	//接收消息
	public void ReciveMessage(String strMessage){
		System.out.println("[" + strType +"]" + "\"" + strName + "\"" + "收到"+strMessage);
	}
}
//定义学生
class Student extends Person {

	public Student(String strName) {
		super(strName);
		strType = "学生";
	}
}

//定义老师
class Teacher extends Person {

	public Teacher(String strName) {
		super(strName);
		strType = "老师";
	}
}
//定义校长
class Principal extends Person {

	public Principal(String strName) {
		super(strName);
		strType = "校长";
	}
}
//定义一个抽象中介
abstract class AbstractMediator {
	//中介的名字
	String strName;
	public AbstractMediator (String strName) {
		this.strName = strName;
	}
	public String getStrName() {
		return strName;
	}
	//定义一个人员列表
	HashMap<String, Person> PersonList = new HashMap<String, Person>();
	public void addPerson(Person onePerson) {
		PersonList.put(onePerson.getStrName(), onePerson);
		onePerson.AddMediator(this);
	}
	public void deletePerson(String strName) {
		PersonList.remove(strName);
	}
	//给所有人发消息
	abstract public void SendMessageToAll(String strMessage);
	//给指定类型的人发消息
	abstract public void SendMessageByType(String strType, String strMessage);
	//给指定名字的人发消息
	abstract public void SendMessageByName(String strName, String strMessage);
}
//定义一个中介(QQ)用于传递消息
class QQMediator extends AbstractMediator{

	public QQMediator(String strName) {
		super(strName);
	}

	@Override
	public void SendMessageToAll(String strMessage) {
		String strQQMessage = "来自QQ消息:" + strMessage;
		for(Entry<String, Person> entry : PersonList.entrySet()){
			entry.getValue().ReciveMessage(strQQMessage);
		}
	}

	@Override
	public void SendMessageByType(String strType, String strMessage) {
		String strQQMessage = "来自QQ消息:" + strMessage;
		for(Entry<String, Person> entry : PersonList.entrySet()){
			if(strType == entry.getValue().getStrType())
			{
				entry.getValue().ReciveMessage(strQQMessage);
			}
		}
	}

	@Override
	public void SendMessageByName(String strName, String strMessage) {
		String strQQMessage = "来自QQ消息:" + strMessage;
		PersonList.get(strName).ReciveMessage(strQQMessage);
	}

}

//定义一个中介(Email)用于传递消息
class EmailMediator extends AbstractMediator{

	public EmailMediator(String strName) {
		super(strName);
	}

	@Override
	public void SendMessageToAll(String strMessage) {
		String strQQMessage = "来自Email消息:" + strMessage;
		for(Entry<String, Person> entry : PersonList.entrySet()){
			entry.getValue().ReciveMessage(strQQMessage);
		}
	}

	@Override
	public void SendMessageByType(String strType, String strMessage) {
		String strQQMessage = "来自Email消息:" + strMessage;
		for(Entry<String, Person> entry : PersonList.entrySet()){
			if(strType == entry.getValue().getStrType())
			{
				entry.getValue().ReciveMessage(strQQMessage);
			}
		}
	}

	@Override
	public void SendMessageByName(String strName, String strMessage) {
		String strQQMessage = "来自Email消息:" + strMessage;
		PersonList.get(strName).ReciveMessage(strQQMessage);
	}

}
public class Mediator {

	public static void main(String[] args) {
		//定义两个学生
		Student student1 = new Student("学生一");
		Student student2 = new Student("学生二");
		//定义两个老师
		Teacher teacher1 = new Teacher("老师一");
		Teacher teacher2 = new Teacher("老师二");
		//定义两个校长
		Principal principal1 = new Principal("校长一");
		Principal principal2 = new Principal("校长二");
		//定义两个中介(QQ和email)
		QQMediator myQQ = new QQMediator("qq");
		EmailMediator myEmail = new EmailMediator("email");
		//将所有人员分别添加到qq和email中
		myQQ.addPerson(student1);
		myQQ.addPerson(student2);
		myQQ.addPerson(teacher1);
		myQQ.addPerson(teacher2);
		myQQ.addPerson(principal1);
		myQQ.addPerson(principal2);
		myEmail.addPerson(student1);
		myEmail.addPerson(student2);
		myEmail.addPerson(teacher1);
		myEmail.addPerson(teacher2);
		myEmail.addPerson(principal1);
		myEmail.addPerson(principal2);
		//下面开始进行通信
		//首先"校长一"通过qq向"校长二"发一条消息
		principal1.SendMessageByName("qq", "校长二", "你觉得什么时候放假好?");
		principal2.SendMessageByName("qq", "校长一", "从明天开始放假吧!");
		principal1.SendMessageByName("qq", "校长二", "好的,那我发通知了");
		//然后"校长一"通过email向所有人员发一条消息
		principal1.SendMessageByType("email", "老师", "老师们都注意了,从明天开始放假");
		//老师收到消息后再给学生发消息
		teacher1.SendMessageByType("email", "学生", "同学们都注意了,从明天开始放假了!");
		//学生收到消息后,开始qq聊起来了
		student1.SendMessageByName("qq", "学生二", "明天放假了,我们去哪玩啊?");
		student2.SendMessageByName("qq", "学生一", "我们去爬山吧,再问问还有没有别人去!");
		student2.SendMessageToAll("email", "明天我们去爬山,还有没有一起去的?");
	}

}

  

二、使用中介者模式的场合和优缺点

使用终结者模式的场合

1.一组定义良好的对象,现在要进行复杂的通信。

2.定制一个分布在多个类中的行为,而又不想生成太多的子类。

可以看出,中介对象主要是用来封装行为的,行为的参与者就是那些对象,但是通过中介者,这些对象不用相互知道。呵呵~~~

使用中介者模式的优点:

1.降低了系统对象之间的耦合性,使得对象易于独立的被复用。

2.提高系统的灵活性,使得系统易于扩展和维护。

使用中介者模式的缺点:

中介者模式的缺点是显而易见的,因为这个“中介“承担了较多的责任,所以一旦这个中介对象出现了问题,那么整个系统就会受到重大的影响。

时间: 2024-08-07 20:24:04

设计模式--14、中介者模式的相关文章

设计模式之中介者模式(Mediator)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

设计模式之中介者模式20170731

行为型设计模式之中介者模式: 一.含义 用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 同事角色与其他同时角色通信的时候,一定要通过中介者角色(中介者封装了各个同事类之间的逻辑关系) 二.代码说明 1.主要有两个角色 1)中介者角色 通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色. 2)同事角色 每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作. 每个同事类的行为分

设计模式(中介者模式-对象去耦)

声明:本系列文章内容摘自<iOS设计模式> 中介者模式 用一个对象来封装一系列对象的交互方式.中介者使个对象不需要显式地相互调用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 何时使用中介者模式 1.对象间的交互虽定义明确然而非常复杂,导致椅子对象彼此相互依赖而且难以理解: 2.因为对象引用了许多其他对象并与其通信,导致对象难以复用: 3.想要制定一个分布在多个对象中的逻辑或行为,又不想生成太多子类. 举个例子 有三个视图,我们可能需要两两之间进行跳转,类比于公司内同时每两个人都有可能

【设计模式】——中介者模式

中介者模式(Mediator),用一个中介者对象来封装一系列的对象交互.中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互. Colleague叫做抽象同事类,而ConcreteColleague是具体同事类,每个具体同事只知道自己的行为,而不了解其他同事类的情况,但它们却都认识中介者对象,Mediator是抽象中介者,定义了同事对象到中介者对象的接口,ConcreteMediator是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事接

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

博文原址:折腾Java设计模式之中介者模式 中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护.中介者模式属于行为型模式. 通俗点来讲就是提供一个中介平台,说到平台,那其实很容易联系到我们很熟悉的房地产中介.我们可以直接通过这个平台得到我们想要的信息,不用对象自身与其他对象交互. 买房子租房子就不需要去找房东,只需要在中介那里获取相应的×××信息.如下图那样,两方只

大话设计模式_中介者模式(Java代码)

中介者模式:用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显示的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 简单描述:1个抽象Colleague,其派生多个具体ConcreteColleague,每个具体ConcreteColleague都认识一个具体中介者.他们发送消息的时候是通过中介者发送.1个中介者,具体中介者认识所有的ConcreteColleague(即持有所有具体ConcreteColleague的引用),它提供向其他具体ConcreteColleag

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

来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_中介者模式.同事协作类.内部类实现 1 package com.test.mediator; 2 /** 3 * 同事类的接口 4 */ 5 public interface Department { 6 void selfAction();//做本部门的事情 7 void outAction();//向总经理发出申请 8 } 1 package com.test.mediator; 2 3 public class

设计模式之: 中介者模式

一.前言 平常我们写一个聊天软件,如果我们只是各个客户端之间连接聊天,那估计我们会写的想哭,那如果我们用服务器作为中间媒介,通过服务器来完成转发,群聊等客户端之间的连接,那样我们就可以最大程度的为各个客户端之间解耦,把它们之间的通信方法抽出来单独实现, 如图1就是不使用中介媒体的时候的结构图: 如图2就是使用我们所说的服务器作为中间媒介的情况的结构图: 二.中介模式 图二就是我们所说的中介模式! 在GOF的<设计模式:可复用面向对象软件的基础>一书中对中介者模式是这样说的:用一个中介对象来封装

C#设计模式(18)——中介者模式(Mediator Pattern)

一.引言 在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室.QQ群和短信平台,这些都是中介者模式在现实生活中的应用,下面就具体分享下我对中介者模式的理解. 二. 中介者模式的介绍 2.1 中介者模式的定义 从生活中的例子可以看出,不论是QQ游戏还是QQ群,它们都是充当一个中间平台,QQ用户可以登录这个中间平台与其他QQ用户进行交流,如果没有这些中间平台,我们如果想与朋友进行聊天的话,可能就需要当面才可以了.电话.短信也同样是一个中间平台,有了这个中间平台,每个用户都不要直接依赖与其

行为型设计模式之中介者模式

结构 意图 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 适用性 一组对象以定义良好但是复杂的方式进行通信.产生的相互依赖关系结构混乱且难以理解. 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象. 想定制一个分布在多个类中的行为,而又不想生成太多的子类. 1 using System; 2 3 class Mediator 4 { 5 private DataProviderColleague