中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。
引言:
尽管一个系统分割成许多对象通常可以增加其可复用性,但是对象间相互连接次数的增加又会降低其可复用性;大量的连接使得一个对象不可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,所以,对系统的行为进行任何较大的改动就十分困难了。
要解决这样的问题,我们可以使用 迪米特原则 ,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果需要相互调用,可以通过第三方来转发。
通过中介者对象,可以将系统的网状结构变成以中介者为中心的星型结构,每个具体对象不再通过直接的联系与另一个具体对象进行通信,而是通过中介者对象。中介者对象的设计使得系统的结构不会因为新对象的引入而造成大量的修改工作。如下图联合国与各个国家的关系就是一个很贴切的例子:
大话设计模式中程杰老师给出的定义是:
中介者模式,用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示的相互引用,从而使其耦合松散,而且可以独立的改变他们之间的交互。
代码实例:
抽象中介者
public abstract class Mediator{
/**
* 定义一个抽象的发送消息方法
* 功能:得到同事对象和发送消息
*/
public abstract void Send(String message,Colleague colleague);
}
抽象同事类
public abstract classColleague{
protected Mediator mediator;
//构造方法,得到中介者对象
public Colleague(){
this.mediator = mediator;
}
}
中介者实现类
public class ConcreteMediator implements Mediator{
private ConcreteMediatorA colleagueA;
private ConcreteMediaorB colleagueB;
//setter and getter
//重写发送消息的方法,根据具体发送消息的对象去通知接收消息的对象
public void send(String message,Colleague colleague){
if(colleague == colleagueA){
colleagueB.notify(message);
}
colleagueA.notify(message);
}
}
同事对象实现类A
public class ConcreteColleagueA implements Colleague{
public ConcreteColleagueA(Mediator mediator){
this.mediator = mediator;
}
public void send(String message){
//消息是通过中介者发送出去的
mediator.send(message,this.concreteColleagueA);
}
public void notify(String message){
Systen.out.println("A同事收到消息:" + message);
}
}
同事对象实现类B
public class ConcreteColleagueB implements Colleague{
public ConcreteColleagueB(Mediator mediator){
this.mediator = mediator;
}
public void send(String message){
//消息是通过中介者发送出去的
mediator.send(message,this.concreteColleagueB);
}
public void notify(String message){
Systen.out.println("B同事收到消息:" + message);
}
}
测试类
public static void main(String[] args){
ConcreteMediator mediator = new ConcreteMediator();
//让两个具体同事类对象认识中介者对象
ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);
mediator.colleagueA = colleagueA;
mediator.colleagueB = colleagueB;
colleagueA.send("hi,nice to meet you!");
colleagueB.send("nice to meet you too!");
}
运行结果:
B同事收到消息:hi,nice to meet you!
A同事收到消息:nice to meet you too!
优点:
1、降低了类的复杂度,将一对多转化成了一对一。
2、各个类之间的解耦。
3、符合迪米特原则。
缺点:中介者会庞大,变得复杂难以维护。
使用场景:
1、系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。
2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
注意事项:不应当在职责混乱的时候使用。
中介者模式的优点来自于集中控制,其缺点也是(中介者对象必须知道所有的同事对象),使用时要考虑清楚。