一起学设计模式 - 中介者模式

文章目录
  1. 1. 概述
  2. 2. 案例
  3. 3. 总结
  4. 4. JDK中应用
  5. 5. 说点什么
  6. 6. 福利

中介者模式(Mediator Pattern)属于行为型模式的一种,用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

概述

在我们的生活中处处充斥着中介者,比如租房、买房、出国留学、找工作、旅游等等可能都需要那些中介者的帮助,同时我们也深受其害,高昂的中介费,虚假信息。在地球上最大的中介者就是联合国了,它主要用来维护国际和平与安全、解决国际间经济、社会、文化和人道主义性质的问题。国与国之间的关系异常复杂,会因为各种各样的利益关系来结成盟友或者敌人,熟话说没有永远的朋友,也没有永远的敌人,只有永远的利益!所以国与国之间的关系同样会随着时间、环境因为利益而发生改变。在我们软件的世界也同样如此,对象与对象之间存在着很强、复杂的关联关系,如果没有类似于联合国这样的“机构”会很容易出问题的,譬如:

1、 对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。

2、 对象之间的连接增加会导致对象可复用性降低。

3、 系统的可扩展性低。增加一个新的对象,我们需要在其相关连的对象上面加上引用,这样就会导致系统的耦合性增高,使系统的灵活性和可扩展都降低。

在前面我就知道如果两个类不必彼此通信,那么这两个类就不应当发生直接关联的关系。如果其中一个类需要调用另一个类中的方法,我们可以通过第三方来转发这个调用。所以对于关系比较复杂的系统,我们为了减少对象之间的关联关系,使之成为一个松耦合系统,我们就需要使用中介者模式。

通过中介者模式,我们可以将复杂关系的网状结构变成结构简单的以中介者为核心的星形结构,每个对象不再和它与之关联的对象直接发生相互作用,而是通过中介者对象来另一个对象发生相互作用。

概述

UML结构图

中介者模式UML结构图

模式结构

  • Mediator(抽象中介者): 定义了同事对象到中介者对象之间的接口
  • ConcreteMediator(具体中介者): 实现抽象中介者的方法,它需要知道所有的具体同事类,同时需要从具体的同事类那里接收信息,并且向具体的同事类发送信息。
  • Colleague(抽象同事类): 它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
  • ConcreteColleague(具体同事类): 抽象同事类的子类;每个同事对象在与其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。

案例

以租房为例,这里中介机构充当租房者与房屋所有者之间的中介者。UML结构图:

UML图如下:

案例UML图

1.定义抽象中介者

1
2
3
4
5
6
7
8
9
10
interface Mediator {

/**
* 让对象之间通讯
* @param content 传递的内容
* @param person 传递的对象
*/
void contact(String content, AbstractPerson person);

}

2.定义抽象同事类AbstractPerson

1
2
3
4
5
6
7
8
9
10
11
12
13
abstract class AbstractPerson {

protected String name;
protected Mediator mediator;

AbstractPerson(String name, Mediator mediator) {
this.name = name;
this.mediator = mediator;
}

public abstract void receiveMessage(String msg);

}

3.分别定义房东租客类,继承抽象同事类

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
class HouseOwner extends AbstractPerson {

HouseOwner(String name, Mediator mediator) {
super(name, mediator);
}

public void contact(String message) {
mediator.contact(message, this);
}

@Override
public void receiveMessage(String message) {
System.out.println("房主:" + name + ",获得信息:" + message);
}
}

class Tenant extends AbstractPerson {

Tenant(String name, Mediator mediator) {
super(name, mediator);
}

public void contact(String message) {
mediator.contact(message, this);
}

@Override
public void receiveMessage(String message) {
System.out.println("租客:" + name + ",获得信息:" + message);
}
}

4.创建具体中介者,抽象的实现,用来协调各个同事之间调用

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
class MediatorStructure implements Mediator {

private HouseOwner houseOwner;
private Tenant tenant;

public HouseOwner getHouseOwner() {
return houseOwner;
}

public void setHouseOwner(HouseOwner houseOwner) {
this.houseOwner = houseOwner;
}

public Tenant getTenant() {
return tenant;
}

public void setTenant(Tenant tenant) {
this.tenant = tenant;
}

@Override
public void contact(String message, AbstractPerson person) {
//如果是房主,则租房者获得信息
if (person == houseOwner) {
tenant.receiveMessage(message);
} else {
//反正则是房主获得信息
houseOwner.receiveMessage(message);
}
}
}

5.创建客户端测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Client {

public static void main(String[] args) {
//一个房主、一个租房者、一个中介机构
MediatorStructure mediator = new MediatorStructure();

HouseOwner owner = new HouseOwner("小唐", mediator);
Tenant tenant = new Tenant("小李", mediator);

mediator.setHouseOwner(owner);
mediator.setTenant(tenant);

tenant.contact("房东您好,请问还有三室两厅出粗吗.....");
owner.contact("还有!你需要租吗?");

}
}

6.运行结果

1
2
房主:小唐,获得信息:房东您好,请问还有三室两厅出粗吗.....
租客:小李,获得信息:还有!你需要租吗?

总结

  • 在中介者模式中通过引用中介者对象,将系统中有关的对象所引用的其他对象数目减少到最少。它简化了系统的结构,将系统由负责的网状结构转变成简单的星形结构,中介者对象在这里起到中转和协调作用。
  • 中介者类是中介者模式的核心,它对整个系统进行控制和协调,简化了对象之间的交互,还可以对对象间的交互进行进一步的控制。
  • 通过使用中介者模式,具体的同事类可以独立变化,通过引用中介者可以简化同事类的设计和实现。
  • 就是由于中介者对象需要知道所有的具体同事类,封装具体同事类之间相互关系,导致中介者对象变得非常复杂,系统维护起来较为困难。

优点

  • 简化了对象之间的关系,将系统的各个对象之间的相互关系进行封装,将各个同事类解耦,使系统成为松耦合系统。
  • 减少了子类的生成。
  • 减少各同事类的设计与实现。

缺点

  • 中介者会庞大,变得复杂难以维护。

JDK中应用

Mediator模式在事件驱动类应用中比较多,例如聊天、消息传递等等,需要有一个MessageMediator,专门负责request/reponse之间任务的调节。

JDK的具体应用:

1
2
3
4
- java.util.Timer
- java.util.concurrent.Executor#execute()
- java.util.concurrent.ExecutorService#submit()
- java.lang.reflect.Method#invoke()

说点什么

参考文献:http://www.cnblogs.com/JsonShare/p/7263876.html

全文代码:https://gitee.com/battcn/design-pattern/tree/master/Chapter15/battcn-mediator

  • 个人QQ:1837307557
  • battcn开源群(适合新手):391619659

微信公众号:battcn(欢迎调戏)

福利

关注公众号:battcn,回复springboot即可获得 <Spring Boot从入门到实战 基础实战系列教程全集><2017最新spring boot 外卖实战微信公众平台视频教程>