中介者模式:用一个中介对象来封装一系列的对象交互。使得各对象不用显式的相互引用,从而使其耦合松散,而且可以独立改变它们之间的交互。
中介者模式
中介者模式 Mediator[ˈmidiˌetɚ] Pattern
:又称为调停者模式,将多对多的相互作用转换为一对多的相互作用,减少对象间的复杂引用关系,使得成为一个松耦合系统。
类图结构
结构解析
Mediator
抽象类,定义中转调用时的方法。
ConcreteMediator
实现类,实现中转调用的逻辑,持有所有需要被中转类的引用。
Colleague
抽象类,仅仅持有一个抽象 Mediator
对象的引用,不定义抽象方法。
ConcreteColleague1/ConcreteColleague2
实现类,定义需要中转的方法。两者并不需要有公共父类,如果需要也仅仅是引用相同的 Mediator
对象。
客户端会将 ConcreteColleague1, ConcreteColleague2, ConcreteMediator
三个对象连接起来,当 ConcreteColleague1
需要调用 ConcreteColleague2
的方法时,并不是直接调用,而是通过 ConcreteMediator.mediate
来中转调用。
Colleague
这个角色并不一定需要,它的作用仅仅是将实现类和 Mediator
关联起来,持有 Mediator
的引用。所以实际使用中 ConcreteColleague1, ConcreteColleague2
也并不是拥有相同父类,只要将他们通过 Mediator
连接起来就行。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| public abstract class Mediator { public abstract void mediate(); }
public abstract class Colleague { protected Mediator mediator;
public Colleague(Mediator mediator) { this.mediator = mediator; } }
public class ConcreteColleague1 extends Colleague { public ConcreteColleague1(Mediator mediator) { super(mediator); }
public void action1() { System.out.println("ConcreteColleague1: Coding to implement " + "requirement. Please release Version."); mediator.mediate(); } }
public class ConcreteColleague2 extends Colleague { public ConcreteColleague2(Mediator mediator) { super(mediator); }
public void action2(){ System.out.println("ConcreteColleague2: Make release version."); } }
public class ConcreteMediator extends Mediator{ private ConcreteColleague1 colleague1; private ConcreteColleague2 colleague2;
@Override public void mediate() { if (colleague2 != null){ colleague2.action2(); } }
public void setColleague1(ConcreteColleague1 colleague1){ this.colleague1 = colleague1; }
public void setColleague2(ConcreteColleague2 colleague2) { this.colleague2 = colleague2; } }
public class TestMediator { public static void main(String[] args) { ConcreteMediator mediator = new ConcreteMediator(); ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator); ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator); mediator.setColleague1(colleague1); mediator.setColleague2(colleague2);
colleague1.action1(); } }
ConcreteColleague1: Coding to implement requirement. Please release Version. ConcreteColleague2: Make release version.
|
中介者模式中需要中转调用的两个类,并不一定需要有相同的父类。父类 Colleague
更多的是确保每个子类必须持有 Mediator
的引用。如上示例中 ConcreteColleague1.action1
对 ConcreteColleague2.action2
的调用,就是通过 ConcreteMediator.mediate
来实现的。
总结
- 中介者模式与迪米特原则
迪米特原则:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某个方法的话,可以通过第三者转发调用。该原则指一个对象应该对于其他对象有最少的了解,有效的降低类之间的耦合。中介者模式是迪米特原则的典型应用。
- 类比
中介者模式,类似电脑的主板协调各个器件工作;系统的各个总线协调驱动程序运行;中介者模式能够将错综复杂的网状图优化成结构清晰的星型图,其中心就是中介者;MVC
架构中的 Control
就是典型的中介者。
所有的 UI
交互系统,如 C#/Form, Android Activity
中的 UI
交互界面,都承担了中介者的角色,它会将 Button, TextView, EditText
等连接起来,这些控件的交互都是通过窗体来中转,响应并显示的。
参考文档
- 大话设计模式
Android
源码设计模式解析与实战
- 中介者模式