引入
书接上回,我们来聊聊啥是中介者模式?
用一个中介对象来封装一系列的对象交互,这个定义大家都能懂,但是这么做有什么好处呢?
在面向对象编程中,如果对象A含有对象B的引用,人们习惯地称B是A的朋友。
如果B是A的朋友,那么对象A就可以请求B执行相关的操作。
但是对于一个庞大的系统来说,涉及到很多对象时,就可能出现对象之间不断引用,就像一个关系网一样牢不可破,但是这样根本不利于系统的扩展和维护,也不利于对象的复用,就像你叫了一个朋友,结果他又叫上了几十个朋友还有几十个兄弟,以后你就不会轻易的叫上他了。
适合用中介者模式的场景
- 许多对象以复杂的方式交互,所导致的依赖关系使系统难以理解和维护
- 一个对象引用其他很多对象,导致难以复用该对象
中介者模式的定义
用一个中介对象来封装一系列的对象交互
中介者模式的结构
应用程序只和中介者发消息,不需要和具体同事做朋友,可以达到解耦的目的。
这个图展开之后应该是这样的,这里就只有一个具体中介者,所以没有写中介者接口如果加上就应该画成下面这样:
具体中介者引用每一个具体同事,每一个同事引用同一个具体中介者,这样做的目的就是让引用更加集中,不会出现系统内部之间胡乱调用的问题,中介者就像一个通讯中转站,同事之间互相不发送消息全部通过中介者去转发,让同事解耦更有利于对象的复用。
同事接口
//同事的接口
public interface Colleague {
public void giveMess(String[] mess);
public void receiverMess(String mess);
public void setName(String name);
public String getName();
}
具体中介者
//由于只涉及到一个中介,所以只设计了一个具体中介者,不需要中介者接口
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;
}
//消息传递函数,mess为字符串数组
public void deliverMess(Colleague colleague,String[] mess){
if(colleague == colleagueA){
if(mess.length >= 2){
colleagueB.receiverMess(colleague.getName()+mess[0]);
colleagueC.receiverMess(colleague.getName()+mess[1]);
}
}
else if(colleague == colleagueB){
if(mess.length >= 2){
colleagueA.receiverMess(colleague.getName()+mess[0]);
colleagueC.receiverMess(colleague.getName()+mess[1]);
}
}
else if(colleague == colleagueC){
if(mess.length >= 2){
colleagueA.receiverMess(colleague.getName()+mess[0]);
colleagueB.receiverMess(colleague.getName()+mess[1]);
}
}
}
}
具体同事
public class ColleagueA implements Colleague{
ConcreteMediator mediator; //具体同事中包含中介者的引用
String name;
ColleagueA(ConcreteMediator mediator){
this.mediator = mediator;
mediator.registerColleagueA(this);//登记
}
@Override
public void giveMess(String[] mess) {
mediator.deliverMess(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 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);
}
}
大家看到这也能想到中介者是不是也可以做一个接口,来达到有多个中介的目的,接口定义用于同事对象之间进行通信的方法,使各对象不需要相互引用。
优点
- 可以避免许多的对象为了之间的通信而相互显示引用,否则系统难于维护,而且也使其他系统难以复用这些对象
- 可以通过中介者将原本分布于多个对象之间的交互行为集中在一起
- 具体中介者使得各个具体同事完全解耦,修改任何一个具体同时的代码不会影响到其他同事
- 具体中介者集中了同事之间如何交互的细节,使系统比较清楚地知道整个系统中的同事是如何交互的
- 当一个对象想交互通信,但又无法相互包含对方的引用,那么使用中介者模式就可以使这些对象互相通信
总结
中介者模式很适合处理多组件的交互,组件之间的交互很复杂的时候,用一个集中的中介去处理这种交互就显得那么合理~