1.定义
中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。
简单来说:用一个中介对象来封装一系列的对象的交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
2.概述
一个对象含有另一个对象的引用是面向对象中经常使用的方式,也是面向对象锁提倡的,即少用继承多用组合。
但是,对于某些特殊系统,特别是涉及很多对象时,该系统可能不希望这些对象直接交互,即不希望这些对象之间互相包含对方的引用,其原因是不利于系统今后的维护,扩展以及对象的复用。
3.应用场景
1、系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。
2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
4.模式的结构与使用
中介者模式的结构中包括四种角色
1.中介者(Mediator):中介者是一个接口,该接口定义了用于同事(Colleague)对象之间进行通信的方法;
2.具体中介者(ConcreteMediator):具体中介者是实现中介者接口的类。具体中介者需要包含所有具体同事(ConcreteColleague)的引用,并通过实现中介者接口中的方法来满足具体同事之间的通信要求;
3.同事(Colleague):一个接口,规定了具体同事需要实现的方法;
4.具体同事(ConcreteColleague):实现了同事接口的类。具体同事需要包含具体中介者的引用,一个具体同事需要和其他具体同事交互时,只需将自己的请求通知给它所包含的具体中介者的引用。
1.中介者模式的UML类图
2.结构的描述
以下通过一个简单的问题来描述中介者模式中所涉及的各个角色。
古代相互交战的A,B,C三方,想通过一个中介者调停之间的战火。A方委托调停者转达的信息是:“要求B方归还曾经抢夺的100斤土豆,要求C方归还曾经抢夺的20头牛”;B方委托调停者转达的信息是:“要求A方归还曾经抢夺的10只公鸡,要求C方归还曾经抢夺的15匹马”;C方委托调停者转达的信息是:“要求A方归还曾经抢夺的300斤小麦,要求B方归还曾经抢夺的50头驴”。
针对以上问题,使用中介者模式设计若干个类。
1.同事(Colleague)
本问题中,同时接口是Colleague,定义了具体同事,即交战各方需要实现的方法,包括giveMess发送消息,receiveMess接受消息,setName设置名称,getName获取名称等方法,具体代码如下所示:
package com.xing.mediator;
public interface Colleague {
public void giveMess(String[] mess);
public void receiveMess(String mess);
public void setName(String name);
public String getName();
}
2.具体中介者(ConcreteMediator)
本问题中,只需要一个具体中介者,并不需要一个中介者(Mediator)接口,具体中介者是ConcreteMediator类,在里面包含了所有同事(Colleague)的引用,还包括deliverMess方法,即实现同事之间消息的传递,具体代码如下:
package com.xing.mediator;
public class ConcreteMediator {
ColleagueA colleagueA;
ColleagueB colleagueB;
ColleagueC colleagueC;
public void registerColleagueA(ColleagueA colleagueA) {
this.colleagueA = colleagueA;
}
public void registerColleagueB(ColleagueB colleagueB) {
this.colleagueB = colleagueB;
}
public void registerColleagueC(ColleagueC colleagueC) {
this.colleagueC = colleagueC;
}
public void deliverMess(Colleague colleague,String[] mess){
if(colleague==colleagueA){
if(mess.length>=2){
colleagueB.receiveMess(colleague.getName()+mess[0]);
colleagueC.receiveMess(colleague.getName()+mess[1]);
}
}else if(colleague==colleagueB){
if(mess.length>=2){
colleagueA.receiveMess(colleague.getName()+mess[0]);
colleagueC.receiveMess(colleague.getName()+mess[1]);
}
}else if(colleague==colleagueC){
if(mess.length>=2){
colleagueA.receiveMess(colleague.getName()+mess[0]);
colleagueB.receiveMess(colleague.getName()+mess[1]);
}
}
}
}
3.具体同事(ConcreteColleague)
对应本问题,有ColleagueA,ColleagueB,ColleagueC三个具体同事,其实例分别表示交战的三方,具体代码如下所示:
ColleagueA.java
package com.xing.mediator;
public class ColleagueA implements Colleague{
ConcreteMediator mediator;//中介者
String name;
public ColleagueA(ConcreteMediator mediator) {
this.mediator = mediator;
mediator.registerColleagueA(this);
}
@Override
public void giveMess(String[] mess) {
mediator.deliverMess(this,mess);
}
@Override
public void receiveMess(String mess) {
System.out.println(name+"收到的信息:");
System.out.println("\t"+mess);
}
@Override
public void setName(String name) {
this.name=name;
}
@Override
public String getName() {
return name;
}
}
ColleagueB.java
package com.xing.mediator;
public class ColleagueB implements Colleague{
ConcreteMediator mediator;//中介者
String name;
public ColleagueB(ConcreteMediator mediator) {
this.mediator = mediator;
mediator.registerColleagueB(this);
}
@Override
public void giveMess(String[] mess) {
mediator.deliverMess(this,mess);
}
@Override
public void receiveMess(String mess) {
System.out.println(name+"收到的信息:");
System.out.println("\t"+mess);
}
@Override
public void setName(String name) {
this.name=name;
}
@Override
public String getName() {
return name;
}
}
ColleagueC.java
package com.xing.mediator;
public class ColleagueC implements Colleague{
ConcreteMediator mediator;//中介者
String name;
public ColleagueC(ConcreteMediator mediator) {
this.mediator = mediator;
mediator.registerColleagueC(this);
}
@Override
public void giveMess(String[] mess) {
mediator.deliverMess(this,mess);
}
@Override
public void receiveMess(String mess) {
System.out.println(name+"收到的信息:");
System.out.println("\t"+mess);
}
@Override
public void setName(String name) {
this.name=name;
}
@Override
public String getName() {
return name;
}
}
4.测试程序
Application.java
package com.xing.mediator;
public class Application {
public static void main(String[] args) {
ConcreteMediator mediator=new ConcreteMediator();//定义中介者
ColleagueA colleagueA=new ColleagueA(mediator);
ColleagueB colleagueB=new ColleagueB(mediator);
ColleagueC colleagueC=new ColleagueC(mediator);
colleagueA.setName("A国");
colleagueB.setName("B国");
colleagueC.setName("C国");
String[] messA={"要求归还曾经抢夺的100斤土豆","要求归还曾经抢夺的20头牛"};
colleagueA.giveMess(messA);
String[] messB={"要求归还曾经抢夺的10只公鸡","要求归还曾经抢夺的15匹马"};
colleagueB.giveMess(messB);
String[] messC={"要求归还曾经抢夺的300斤小麦","要求归还曾经抢夺的50头驴"};
colleagueC.giveMess(messC);
}
}
5.测试结果展示
5.中介者模式的优点
1、降低了类的复杂度,将一对多转化成了一对一。
2、各个类之间的解耦。
3、符合迪米特原则。
4、可以避免许多的对象为了之间的通信而相互显示引用,否则,不仅系统难于维护,而且也使其他系统难以复用这些对象。