中介者模式

中介者模式

中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。

通俗理解,把复杂的网状结构关系分离为星型结构关系。

img

中介者模式4种角色:

  • 抽象中介者(Mediator)角色:抽象中介者角色定义统一的接口,以及一个或者多个事件方法,用于各同事角色之间的通信。
  • 具体中介者(ConcreteMediator)角色:实现了抽象中介者所声明的事件方法,协调各同事类之间的行为,持有所有同事类对象的引用。
  • 抽象同事(Colleague)角色:定义了抽象同事类,持有抽象中介者对象的引用。
  • 具体同事(ConcreteColleague)角色:继承抽象同事类,实现自己业务,通过中介者跟其他同事类进行通信。

例子

需求:

点击Button新增信息,List和ComboBox也需要新增信息

点击List选中信息,ComboBox也要选中信息,TextBox新增信息

点击ComboBox选中信息,List也要选中信息,TextBox新增信息

可以使用中介者来统一管理同事类之间的通信,来达到解耦的效果

image-20231229112149209

抽象同事类

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() {
//Button不产生响应
}
}
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();
//创建4个同事
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();
}
}

image-20231229112057538

优点

  • 各个类之间的解耦,方便复用各个组件,降低了类的复杂度,将一对多转化成了一对一。
  • 单一职责原则,可以将多个组件间的交流抽取到同一位置,使其更易于理解和维护。
  • 开闭原则,组件关系包含在中介者中,无需修改组件就能新增中介者,定义新的合作方式。

缺点

  • 中介者会庞大,变得复杂难以维护,一段时间后,中介者可能会演化成为上帝对象。
  • 中介者角色承担了较多的责任,一旦中介者对象出现问题,整个系统将受到重大影响。
  • 新增组件类时,需要修改抽象中介者和具体中介者,可以使用观察者模式和状态模式来优化这个问题。

典型应用场景

  • 现实生活中的各种交互平台(比如交易所,超市,集市,购物广场,交易会,网络论坛等),特别注意,现实中的很多中介公司(比如留学服务中介等)的中介含义还是与中介模式中的中介含义不太一样,它们除了体现一种“中介”外,还有“代理”的味道在里面。中介模式中的中介其实仅提供一个交互的平台,具体的交互还是对象之间来完成的
  • 开发系统中的用户UI界面。
  • 电脑主板,电脑的CPU、内存、显卡等配件之间不需要相互交互,通过主板即可,这也是中介者模式的典型应用。

中介者模式与门面模式

中介者模式与门面模式虽然有类似的功能,但两者之间的区别还是很大的,门面模式时为用户使用一系列的对象提供一个简化的接口,更多体现的是一种“代理”而不是“中介”;而中介者模式主要是为一系列的对象提供一个交互的场所,中介者对象封装了一系列对象之间的交互,中介者模式中没有用户的角色概念,也不向外提供服务。


中介者模式
http://example.com/2023/10/15/计算机基础/设计模式/16-中介者模式/
作者
PALE13
发布于
2023年10月15日
许可协议