1.概述
用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。
对于一个模块或者系统,可能由很多对象构成,而且这些对象之间可能存在相互的引用,在最坏的情况下,每一个对象都知道其他所有的对象,这无疑复杂化了对象之间的联系。虽然将一个系统分割成许多对象通常可以增强可复用性,但是对象间相互连接的激增又会降低其可复用性,大量的相互连接使得一个对象似乎不太可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,而且对系统的行为进行任何较大的改动都会十分困难。结果是你不得不定义大量的子类以定制系统的行为。因此,为了减少对象两两之间复杂的引用关系,使之成为一个松耦合的系统,我们需要使用中介者模式
2.涉及到的角色
抽象中介者(Mediator):中介者定义一个接口用于与各同事(Colleague)对象通信。
具体中介者(ConcreteMediator):具体中介者通过协调各同事对象实现协作行为。了解并维护
抽象同事类(Colleague class):定义同事类接口,定义各同事的公有方法.
具体同事类(ConcreteColleague):实现抽象同事类中的方法。每一个同时类需要知道中介者对象;每个具体同事类只需要了解自己
的行为,而不需要了解其他同事类的情况。每一个同事对象在需与其他的同事通信的时候,与它的中介者通信。
3.适用性
一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如有六个同事类对象,假如对象1发生变化,会有4个对象受到影响。如果对象2发生变化,那么会有5个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。
如果引入中介者模式,那么同事类之间的关系将变为星型结构,任何一个类的变动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。
4.结构
5.中介者模式的优缺点
中介者模式的优点:
1) 减少了子类生成: Mediator将原本分布于多个对象间的行为集中在一起。改变这些行为只需生成Mediator的子类即可。这样各个Colleague类可被重用。
2) 简化各同事类的设计和实现 :它将各同事类Colleague解耦,Mediator有利于各Colleague间的松耦合.你可以独立的改变和复用各
Colleague类和Mediator类。
3) 它简化了对象协议:用Mediator和各Colleague间的一对多的交互来代替多对多的交互。一对多的关系更易于理解、维护和扩展。
4) 它对对象如何协作进行了抽象 将中介作为一个独立的概念并将其封装在一个对象中,使你将注意力从对象各自本身的行为转移到它
们之间的交互上来。这有助于弄清楚一个系统中的对象是如何交互的。
5) 它使控制集中化 中介者模式将交互的复杂性变为中介者的复杂性。
中介者模式的缺点:
因为中介者封装了协议,即在具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复杂,这可能使得中介者自身成为一个难于维护的
庞然大物。
6.实例代码:
抽象中介者接口:
package com.mediator;
/**
* @author lxp
*
* @TODO
*
*/
// 定义抽象中介者接口
public interface Mediator {
//发送消息
public abstract void sendMess(String mess, Colleague colleague);
}
抽象同事接口:
package com.mediator;
/**
* @author lxp
*
* @TODO
*
*/
//定义抽象同事接口
public interface Colleague {
//发送消息
public abstract void giveMess(String mess);
//接收消息
public abstract void reciveMess(String mess);
}
具体中介中者类:
package com.mediator;
/**
* @author lxp
*
* @TODO
*
*/
// 定义具体中介者
public class ConcreteMediator implements Mediator {
private ConcreteColleagueOne colleagueOne;
private ConcreteColleagueTwo colleagueTwo;
//具体中介者包含所有同事的引用
public void setColleagueOne(ConcreteColleagueOne colleagueOne) {
this.colleagueOne = colleagueOne;
}
public void setColleagueTwo(ConcreteColleagueTwo colleagueTwo) {
this.colleagueTwo = colleagueTwo;
}
@Override
public void sendMess(String mess, Colleague colleague) {
// TODO Auto-generated method stub
if (colleague == colleagueOne) {
System.out.println("colleagueOne发送消息:"+mess);
colleagueTwo.reciveMess(mess);
} else if (colleague == colleagueTwo){
System.out.println("colleagueTwo发送消息:"+mess);
colleagueOne.reciveMess(mess);
}
}
}
具体同事类:
package com.mediator;
/**
* @author lxp
*
* @TODO
*
*/
public class ConcreteColleagueOne implements Colleague {
private ConcreteMediator mediotor;
public ConcreteColleagueOne( ConcreteMediator mediator) {//具体同事包含具体中介者的引用
// TODO Auto-generated constructor stub
this.mediotor=mediator;
}
@Override
public void giveMess(String mess) {
// TODO Auto-generated method stub
mediotor.sendMess(mess, this);
}
@Override
public void reciveMess(String mess) {
// TODO Auto-generated method stub
System.out.println("colleagueOne收到消息:"+mess);
}
}
package com.mediator;
/**
* @author lxp
*
* @TODO
*
*/
public class ConcreteColleagueTwo implements Colleague {
private ConcreteMediator mediotor;
public ConcreteColleagueTwo( ConcreteMediator mediator) {//具体同事包含具体中介者的引用
// TODO Auto-generated constructor stub
this.mediotor=mediator;
}
@Override
public void giveMess(String mess) {
// TODO Auto-generated method stub
//System.out.println("ColleagueTwo发送消息:"+mess);
mediotor.sendMess(mess, this);
}
@Override
public void reciveMess(String mess) {
// TODO Auto-generated method stub
System.out.println("colleagueTwo收到消息:"+mess);
}
}
测试类:
package com.mediator;
/**
* @author lxp
*
* @TODO
*
*/
public class MediatorDemo {
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleagueOne colleagueOne = new ConcreteColleagueOne(mediator);
ConcreteColleagueTwo colleagueTwo = new ConcreteColleagueTwo(mediator);
mediator.setColleagueOne(colleagueOne);
mediator.setColleagueTwo(colleagueTwo);
colleagueOne.giveMess("你好colleagueTwo,很高兴认识你!");
colleagueTwo.giveMess("你好colleagueOne,我也很高兴认识你!");
}
}
试验结果: