中介者模式
中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。
通俗理解,把复杂的网状结构关系分离为星型结构关系。

中介者模式4种角色:
- 抽象中介者(Mediator)角色:抽象中介者角色定义统一的接口,以及一个或者多个事件方法,用于各同事角色之间的通信。
- 具体中介者(ConcreteMediator)角色:实现了抽象中介者所声明的事件方法,协调各同事类之间的行为,持有所有同事类对象的引用。
- 抽象同事(Colleague)角色:定义了抽象同事类,持有抽象中介者对象的引用。
- 具体同事(ConcreteColleague)角色:继承抽象同事类,实现自己业务,通过中介者跟其他同事类进行通信。
例子
需求:
点击Button新增信息,List和ComboBox也需要新增信息
点击List选中信息,ComboBox也要选中信息,TextBox新增信息
点击ComboBox选中信息,List也要选中信息,TextBox新增信息
可以使用中介者来统一管理同事类之间的通信,来达到解耦的效果
抽象同事类
1 2 3 4 5 6 7 8 9 10 11
| public abstract class Component { protected Mediator mediator; public void setMediator(Mediator mediator){ this.mediator = mediator; } public void change(){ mediator.componentChangeed(this); } public abstract void update(); }
|
具体同事类
1 2 3 4 5 6
| public class Button extends Component{ @Override public void update() { } }
|
1 2 3 4 5 6 7 8 9 10
| public class ComboBox extends Component{ @Override public void update() { System.out.println("组合框新增一项"); } public void select(){ System.out.println("组合框选中一项"); } }
|
1 2 3 4 5 6 7 8 9 10
| public class List extends Component{ @Override public void update() { System.out.println("列表新增一项"); } public void select(){ System.out.println("列表中选中一项"); } }
|
1 2 3 4 5 6 7
| public class TextBox extends Component{ @Override public void update() { System.out.println("文本框显示信息"); } }
|
抽象中介者
1 2 3
| public abstract class Mediator { public abstract void componentChangeed(Component c); }
|
具体中介者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class ConcreteMediator extends Mediator{ public Button button; public List list; public TextBox textBox; public ComboBox comboBox;
@Override public void componentChangeed(Component c) { if(c == button){ System.out.println("--点击增加按钮--"); list.update(); comboBox.update(); }else if(c == list){ System.out.println("--从列表框选择客户--"); comboBox.select(); textBox.update(); }else if(c == comboBox){ System.out.println("--从组合框选择客户--"); list.select(); textBox.update(); } } }
|
客户端
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
| public class Client { public static void main(String[] args) { ConcreteMediator mediator = new ConcreteMediator(); Button button = new Button(); List list = new List(); ComboBox comboBox = new ComboBox(); TextBox textBox = new TextBox();
button.setMediator(mediator); list.setMediator(mediator); comboBox.setMediator(mediator); textBox.setMediator(mediator);
mediator.button = button; mediator.list = list; mediator.comboBox = comboBox; mediator.textBox = textBox;
button.change(); list.change(); } }
|

优点
- 各个类之间的解耦,方便复用各个组件,降低了类的复杂度,将一对多转化成了一对一。
- 单一职责原则,可以将多个组件间的交流抽取到同一位置,使其更易于理解和维护。
- 开闭原则,组件关系包含在中介者中,无需修改组件就能新增中介者,定义新的合作方式。
缺点
- 中介者会庞大,变得复杂难以维护,一段时间后,中介者可能会演化成为上帝对象。
- 中介者角色承担了较多的责任,一旦中介者对象出现问题,整个系统将受到重大影响。
- 新增组件类时,需要修改抽象中介者和具体中介者,可以使用观察者模式和状态模式来优化这个问题。
典型应用场景
- 现实生活中的各种交互平台(比如交易所,超市,集市,购物广场,交易会,网络论坛等),特别注意,现实中的很多中介公司(比如留学服务中介等)的中介含义还是与中介模式中的中介含义不太一样,它们除了体现一种“中介”外,还有“代理”的味道在里面。中介模式中的中介其实仅提供一个交互的平台,具体的交互还是对象之间来完成的
- 开发系统中的用户UI界面。
- 电脑主板,电脑的CPU、内存、显卡等配件之间不需要相互交互,通过主板即可,这也是中介者模式的典型应用。
中介者模式与门面模式
中介者模式与门面模式虽然有类似的功能,但两者之间的区别还是很大的,门面模式时为用户使用一系列的对象提供一个简化的接口,更多体现的是一种“代理”而不是“中介”;而中介者模式主要是为一系列的对象提供一个交互的场所,中介者对象封装了一系列对象之间的交互,中介者模式中没有用户的角色概念,也不向外提供服务。