一、中介者模式定义
中介者模式定义:用一个中介者对象来封装一系列的对象的交互,使各个对象间不需要显示的相互调用, 从而使其松耦合。
概念总是抽象的,我们用两个图来表示一下。
如果对象和对象直接直接作用,则耦合性较强, 如果一个类发生了改变,比如方法参数改变,其他相关的类都得进行变化, 这就是一种强耦合的方式, 这个时候, 如果引入中介者, 则可以降低类之间的耦合:
就像上面两张图, 国与国之间要商量事情, 如果要一个一个单独沟通,那很累的,所以搞一个联合国吧, 大家都在这里来交流,有什么事都在联合国处理。大家相互之间不直接联系,都是通过联合国来交流。所有的事情也通过联合国来统一调度(当然,这里只是一个类比而已, 主要是为了理解概念)。
其实中介者模式就是代码设计六大原则之迪米特法则的一种应用,关于代码设计六大原则, 在前面的博客中单独讲到过,这里就不赘述。
二、中介者模式示例代码
理解了中介者模式的概念, 我们看一下如何去简单使用中介者模式, 首先看一下结构图:
中介者模式通常定义了一个抽象的中介者Mediator, 具体的中介者子类会去实现对应的功能, 然后每个具体的同事类都继承自一个抽象类或者接口。各个同事类之间不直接交互, 都通过中介者来进行交互。
简单举例, 先定义一个抽象中介者:
public abstract class Mediator {
protected ConcreteColleague1 c1;
protected ConcreteColleague2 c2;
public abstract void doSomething1();
public abstract void doSomething2();
}
ConcreteMediator 类:
public class ConcreteMediator extends Mediator {
@Override
public void doSomething1() {
System.out.println("ConcreteMediator----doSomething1()");
super.c1.doSelfMethod();
super.c2.doSelfMethod();
}
@Override
public void doSomething2() {
System.out.println("ConcreteMediator----doSomething2()");
super.c1.doSelfMethod();
super.c2.doSelfMethod();
}
}
Colleague类:
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator _mediator){
this.mediator = _mediator;
}
public abstract void doSelfMethod();
public abstract void doDepMethod();
}
具体同事类:
ConcreteColleague1:
public class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator _mediator) {
super(_mediator);
}
@Override
public void doSelfMethod() {
System.out.println("ConcreteColleague1----doSelfMethod()");
}
@Override
public void doDepMethod() {
System.out.println("ConcreteColleague1----doDepMethod()");
super.mediator.doSomething1();
}
}
ConcreteColleague2:
public class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator _mediator) {
super(_mediator);
}
@Override
public void doSelfMethod() {
System.out.println("ConcreteColleague2----doSelfMethod()");
}
@Override
public void doDepMethod() {
System.out.println("ConcreteColleague2----doDepMethod()");
//super.mediator.doSomething1();
super.mediator.doSomething2();
}
}
在业务代码中使用:
public class Client {
public static void main(String[] args) {
Mediator mediator = new ConcreteMediator();
ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);
ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);
mediator.setC1(colleague1);
mediator.setC2(colleague2);
System.out.println("-------------------------------------");
colleague1.doSelfMethod();
System.out.println("-------------------------------------");
colleague1.doDepMethod();
System.out.println("-------------------------------------");
colleague2.doSelfMethod();
System.out.println("-------------------------------------");
colleague2.doDepMethod();
System.out.println("-------------------------------------");
}
}
在上述例子中, 两个同事类并没有持有对方的对象直接交流, 而是通过中介者类来完成。
广义的中介者
上面提到的中介者模式是很多书上提到的一种标准示例用法, 实际上,模式不是固定的, 我们完全可以按照自己的需求来使用,定义模式的概念主要是为了让我们理解这种模式,最主要的还是完成代码的松耦合。
在实际开发中,经常会简化中介者模式,来是开发变得简单,比如有如下的简化。
通常会去掉同事对象的父类,这样可以让任意的对象,只需要有交互,就可以成为同事, 并不一定要继承同一个抽象类或接口
通常不定义Mediator接口,直接把具体的中介者对象实现成为单例,
同事对象不再持有中介者,而是在需要的时候直接获取中介者对象并调用;中介者也不再持有同事对象,而是在具体处理方法里面去创建,或获取,或从数据传入需要的同事对象。
经过这样的简化、变形的情况称为广义中介者。
在本文前两篇的Loader/LoaderManager的源码分析中, 就看到了中介者的使用,Activity不直接和LoaderManager进行交互, 而是用过一个中介者 FragmentHostCallback去获取LoaderManager的实例。