中介者模式(Mediator Pattern)属于行为型模式,它用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
比如 MVC 模式,C(Controller 控制器)是 M(Model 模型)和 V(View 视图)的中介者,在前后端交互时起 到了中间人的作用。
中介者模式中,中介者对象处于核心地位,它主要有两个作用:
结构上起到中转作用。通过中介对象对关系的封装,使得具体的同事类不再需要显式地引用其他对象,它只需要通过中介者就可以完成其他同事类之间的通信。行为上起到协作作用。中介者对同事类之间的关系进行封装,同事类在不需要知道其他对象的情况下通过中介者与其他对象完成通信。在这个过程中同事类是不需要指明中介者该如何做,中介者可以根据自身的逻辑来进行协调,对同事的请求进一步处理,将同事成员之间的关系行为进行分离和封装。代码例子来源于这篇博客 23种设计模式(7):中介者模式,这篇博客写得很好,建议大家看一看。
有两个类A和B,类中各有一个数字,并且要保证类B中的数字永远是类A中数字的100倍。也就是说,当修改类A的数时,将这个数字乘以100赋给类B,而修改类B时,要将数除以100赋给类A。类A类B互相影响,就称为同事类。代码如下:
abstract class AbstractColleague { protected int number; public int getNumber() { return number; } public void setNumber(int number){ this.number = number; } //抽象方法,修改数字时同时修改关联对象 public abstract void setNumber(int number, AbstractColleague coll); } class ColleagueA extends AbstractColleague{ public void setNumber(int number, AbstractColleague coll) { this.number = number; coll.setNumber(number*100); } } class ColleagueB extends AbstractColleague{ public void setNumber(int number, AbstractColleague coll) { this.number = number; coll.setNumber(number/100); } } public class Client { public static void main(String[] args){ AbstractColleague collA = new ColleagueA(); AbstractColleague collB = new ColleagueB(); System.out.println("==========设置A影响B=========="); collA.setNumber(1288, collB); System.out.println("collA的number值:"+collA.getNumber()); System.out.println("collB的number值:"+collB.getNumber()); System.out.println("==========设置B影响A=========="); collB.setNumber(87635, collA); System.out.println("collB的number值:"+collB.getNumber()); System.out.println("collA的number值:"+collA.getNumber()); } }上面的代码中,类A类B通过直接的关联发生关系,假如我们要使用中介者模式,类A类B之间则不可以直接关联,他们之间必须要通过一个中介者来达到关联的目的。
abstract class AbstractColleague { protected int number; public int getNumber() { return number; } public void setNumber(int number){ this.number = number; } //注意这里的参数不再是同事类,而是一个中介者 public abstract void setNumber(int number, AbstractMediator am); } class ColleagueA extends AbstractColleague{ public void setNumber(int number, AbstractMediator am) { this.number = number; am.AaffectB(); } } class ColleagueB extends AbstractColleague{ @Override public void setNumber(int number, AbstractMediator am) { this.number = number; am.BaffectA(); } } abstract class AbstractMediator { protected AbstractColleague A; protected AbstractColleague B; public AbstractMediator(AbstractColleague a, AbstractColleague b) { A = a; B = b; } public abstract void AaffectB(); public abstract void BaffectA(); } class Mediator extends AbstractMediator { public Mediator(AbstractColleague a, AbstractColleague b) { super(a, b); } //处理A对B的影响 public void AaffectB() { int number = A.getNumber(); B.setNumber(number*100); } //处理B对A的影响 public void BaffectA() { int number = B.getNumber(); A.setNumber(number/100); } } public class Client { public static void main(String[] args){ AbstractColleague collA = new ColleagueA(); AbstractColleague collB = new ColleagueB(); AbstractMediator am = new Mediator(collA, collB); System.out.println("==========通过设置A影响B=========="); collA.setNumber(1000, am); System.out.println("collA的number值为:"+collA.getNumber()); System.out.println("collB的number值为A的10倍:"+collB.getNumber()); System.out.println("==========通过设置B影响A=========="); collB.setNumber(1000, am); System.out.println("collB的number值为:"+collB.getNumber()); System.out.println("collA的number值为B的0.1倍:"+collA.getNumber()); } }上面例子和代码来自我提到的那篇博客。但是我觉得在AbstractMediator可以使用 Map 来管理AbstractColleague而不是使用成员属性,如果AbstractColleague数量太多的话,用 Map 来管理更好,然后在每个ConcreteColleague中直接使用名字来调用相应的方法。
多个类相互耦合,会形成网状结构, 使用中介者模式将网状结构分离为星型结构,进行解耦
减少类间依赖,降低了耦合,符合迪米特原则
中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响
如果设计不当,中介者对象本身变得过于复杂,这点在实际使用时,要特别注意
参考资料: 设计模式读书笔记-----中介者模式
23种设计模式(7):中介者模式
尚硅谷 Java 设计模式课程笔记。
