介绍
中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。
例如,在一个房屋租赁系统中,有很多求租者和出租者,如果要求他们之间必须认识才能进行有关租赁的操作,显然不利于系统的维护和发展。因此,每当有新的出租者或求租者加入该系统,这个新的加入者必须和现有系统中的所有人认识后才能和他们进行有关租赁的操作。
一个好的解决办法就是在房屋租赁系统中建立一个称作中介者的对象,中介者包含系统中所有其他对象的引用,而系统中的其他对象只包含中介者的引用,也就是说中介者和大家互相认识、中介者使系统中的其他对象完全解耦,当系统中对象之间需要做交互时,只需将自己的请求通知中介者即可,如果有新的加入者,该加入者只需含有中介者的引用,并让中介者含有自己的引用,他就可以和系统中其他对象进行有关租赁操作。
应用场景
系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。
模式结构
(1)中介者(Mediator):中介者是一个接口,该接口定义了用于同事对象之间进行通信的方法。
(2)具体中介者(ConcreteMediator):具体中介者是实现中介者接口的类。具体中介者需要包含所有具体同事的引用,并通过实现中介者接口中的方法来满足具体同事之间的通信请求。
(3)同事(Colleague):一个接口,规定了具体同事需要实现的方法。
(4)具体同事(ConcreteColleague):实现同事接口的类。具体同事需要包含具体中介者的引用,一个具体同事需要和其他具体同事交互时,只需要将自己的请求通知给它所包含的具体中介者即可。
代码案例
首先,创建Colleague接口:
public interface Colleague {
void giveMess(String[] mess);
void receiverMess(String mess);
void setName(String name);
String getName();
}
创建实现类:
public class ColleagueA implements Colleague {
private ConcreteMediator mediator;
private String name;
ColleagueA(ConcreteMediator mediator){
this.mediator = mediator;
mediator.registerColleagueA(this);
}
@Override
public void giveMess(String[] mess) {
mediator.deliveMess(this, mess);
}
@Override
public void receiverMess(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;
}
}
public class ColleagueB implements Colleague {
private ConcreteMediator mediator;
private String name;
ColleagueB(ConcreteMediator mediator){
this.mediator = mediator;
mediator.registerColleagueB(this);
}
@Override
public void giveMess(String[] mess) {
mediator.deliveMess(this, mess);
}
@Override
public void receiverMess(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;
}
}
public class ColleagueC implements Colleague {
private ConcreteMediator mediator;
private String name;
ColleagueC(ConcreteMediator mediator){
this.mediator = mediator;
mediator.registerColleagueC(this);
}
@Override
public void giveMess(String[] mess) {
mediator.deliveMess(this, mess);
}
@Override
public void receiverMess(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;
}
}
创建中介者:
public class ConcreteMediator {
private ColleagueA colleagueA;
private ColleagueB colleagueB;
private 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 deliveMess(Colleague colleague , String[] mess){
if(colleague == colleagueA){
if(mess.length >= 2){
colleagueB.receiverMess(colleague.getName()+mess[0]);
colleagueC.receiverMess(colleague.getName()+mess[1]);
}
}
if(colleague == colleagueB){
if(mess.length >= 2){
colleagueA.receiverMess(colleague.getName()+mess[0]);
colleagueC.receiverMess(colleague.getName()+mess[1]);
}
}
if(colleague == colleagueC){
if(mess.length >= 2){
colleagueA.receiverMess(colleague.getName()+mess[0]);
colleagueB.receiverMess(colleague.getName()+mess[1]);
}
}
}
}
测试类:
public class ApplicationTest {
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 = {"要求B方归还曾抢夺的100斤土豆" , "要求C方归还曾抢夺的20头牛"};
colleagueA.giveMess(messA);
System.out.println("----------------------------------------------");
String[] messB = {"要求A方归还曾抢夺的10只公鸡" , "要求C方归还曾抢夺的15匹马"};
colleagueB.giveMess(messB);
}
}
优点
(1)可以避免许多的对象为了通信而相互显式引用,否则,不仅系统难于维护,而且也使其他系统难以复用这些对象。
(2)具体中介者使得各个具体同事完全解耦,修改任何一个具体同事的代码不会影响到其他同事。
(3)具体中介者集中了同事之间是如何交互的细节,使系统比较清楚地知道整个系统中的同事是如何交互的。
缺点
中介者类会变得庞大