定义:
用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。
设计类图:
中介者模式中的角色:
- Mediator抽象中介者:定义同事类对象到中介者对象的接口,用于各个同事类之间的通信。
- ConcreteMediator具体中介者:实现了抽象中介者所声明的方法,知晓所有的具体同事类,负责协调各同事对象的交互关系。因此它是依赖于各个具体同事类的。
- Colleague抽象同事类:定义出中介者到同事对象的接口。同事对象只知道中介者而不知道其余的同事对象。
- ConcreteColleague具体同事类:抽象同事类的实现类,每一个同事角色都知道中介者角色,而且与其他的同事角色的通信,一定要通过中介者角色协作。每个同事类的行为分为两种:一种是同事本身的行为,比如改变对象本身的状态,处理自己的行为等,这种方法叫做自发行为,与其他的同事类或中介者没有任何的依赖。第二种是必须依赖中介者才能完成的行为,叫做依赖方法。
示例代码:
public interface Mediator {
public void callColleagueA();
public void callColleagueB();
}
public class ConcreteMediator implements Mediator {
private ConcreteColleagueA colleagueA;
private ConcreteColleagueB colleagueB;
@Override
public void callColleagueA() {
this.colleagueA.operation1();
}
@Override
public void callColleagueB() {
this.colleagueB.operation2();
}
public void setColleagueA(ConcreteColleagueA colleagueA) {
this.colleagueA = colleagueA;
}
public void setColleagueB(ConcreteColleagueB colleagueB) {
this.colleagueB = colleagueB;
}
}
public abstract class Colleague {
private Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public Mediator getMediator() {
return this.mediator;
}
}
public class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(Mediator mediator) {
super(mediator);
}
public void operation1() {
System.out.println("ColleagueA自己的业务行为");
}
public void operation2() {
//...do something
//通过中介者调用ColleagueB的方法行为
getMediator().callColleagueB();
}
}
public class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(Mediator mediator) {
super(mediator);
}
public void operation1() {
//...do something
//通过中介者调用ColleagueA的方法行为
getMediator().callColleagueA();
}
public void operation2() {
System.out.println("ColleagueB自己的业务行为");
}
}
public class Client {
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);
mediator.setColleagueA(colleagueA);
mediator.setColleagueB(colleagueB);
System.out.println("-----开始执行ColleagueA业务逻辑-----");
colleagueA.operation1();
colleagueA.operation2();
System.out.println("-----开始执行ColleagueB业务逻辑-----");
colleagueB.operation1();
colleagueB.operation2();
}
}
输出结果:
可以看到ConcreteColleagueA和ConcreteColleagueB中除了执行自己的业务方法之外,还会相互调用对方的业务方法,而相互调用都是通过ConcreteMediator中介者类来实现的,而不是直接调用对方的方法,ConcreteColleagueA和ConcreteColleagueB之间没有任何直接的依赖关系。
如图,中介者模式使得原来各个类之间的复杂网状结构变成星型结构,它的最大的优势就是减少了各个类之间的复杂依赖关系,原来每个同事类之间可能需要直接依赖多个其他同事类,那么引入中介者之后每个同事类就不需要再与其他任何同事类有直接的关系,与其他同事类的交互都是通过中介者角色来完成,可以说中介者角色在这里承担了一个类似调度指挥中心的任务角色。
中介者模式的优点
前面已经提到过,最大的优点就是减少类之间的依赖,将原来一对多的依赖变成一对一的依赖,使得类之间关系变得松耦合。将复杂的逻辑交互交由中介者集中处理控制,方便管理。
中介者模式的缺点
缺点就是中介者的类内部逻辑可能会变得很复杂,甚至很臃肿,因为中介者将原来各个类之间的交互逻辑都承包了,如果原来的各个类之间的交互逻辑过多过于复杂,或者同事类的数量过多,中介者类的内部逻辑就会爆炸,难以维护。
使用场景
实际当中,有很多场景适用中介者模式,比如机场调度中心,房产中介等,在我们熟悉的MVC框架中的C,MVP框架中的P,都可以看做是中介者模式,通常情况下我们所写的类一定会与其他类有依赖关系的,但是是否要采用中介者模式还是要慎重考虑,因为它带来优势的同时也可能会带来灾难,原本几个简单的类的依赖,可能加入中介者反而会变得更加复杂,而原本那些依赖关系已经复杂到混乱不堪的程度的,可能需要做的是重构而不是引入新的模式。
参考: