在现实生活中,常常会出现好多对象之间存在复杂的交互关系,这种交互关系常常是 “网状结构”,它要求每个对象都必须知道它需要交互的对象。例如,班长和团支书等干部需要记住同学们的电话,且同学中如果有人的电话修改了,需要告诉所有干部,自己的手机号修改了,这叫作 “牵一发而动全身”,非常复杂。如果把这种 “网状结构” 改为 “星形结构” 的话,将大大降低它们之间的 “耦合性”,这时只要找一个 “中介者” 就可以了。如前面所说的问题,只要在网上建立一个每个干部都可以访问的 “通信录”(中介)就解决了。这样的例子还有很多,例如,你刚刚工作想租房,可以找 “房屋中介”;或者,自己刚刚到一个陌生城市找工作,可以找 “人才交流中心 ”帮忙。软件的开发过程中,这样的例子也很多,例如,在 MVC 框架中,控制器(C)就是模型(M)和视图(V)的中介者,它将大大降低对象之间的耦合性,提高系统的灵活性。

# 一、中介者模式的定义与优缺点

【1】中介者模式(Mediator): 定义一个中介对象来封装一些列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变他们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型代表。
【2】中介者模式是一种对象行为模式,其主要优点如下: ①、降低了对象之间的耦合性,使得对象易于独立地被复用。②、将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。
【3】中介者模式主要缺点如下: ①、当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。②、中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响。
【4】使用场景: 1、系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。 2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
【5】注意事项: 不应当在职责混乱的时候使用。

# 二、中介者模式的结构与类图

中介者模式的关键点是找出 “中介者”,中介者模式包含一下主要角色:
【1】抽象中介者(Mediator)角色: 它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
【2】具体中介者(ConcreteMediator)角色: 实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
【3】抽象同事类(Colleague)角色: 定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
【4】具体同事类(Concrete Colleague)角色: 是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。

中介者模式

# 三、中介者模式案例分析

【1】抽象中介者(Mediator)角色: 包含将租客注入到集合中的方法 register 和 租客发送需求后需要进行业务逻辑处理(调用其他租客的信息或房东信息进行匹配)的方法 getMessage

public interface Mediator {
    //注册同事类
    public void register(Colleague colleague);
    //获取消息
    public void getMessage(Colleague colleague);
}
1
2
3
4
5
6

【2】具体中介者(ConcreteMediator)角色: 对中介者接口的实现,这里存储租客对象的集合为 Map 将租客类名作为 Key 存储,并在 getMessage 方法中,将与请求租客信息相符的需求进行反馈。

package mediator;
 
import java.util.HashMap;
import java.util.Map;
 
public class ConcreteMediator implements Mediator{
    //创建存放 mediator 的集合 map
    Map<String, Colleague> mediators = new HashMap<>();
 
    @Override
    public void register(Colleague colleague) {
        if(colleague instanceof Colleague_A) {
            mediators.put("colleague_A", colleague);
        }else if(colleague instanceof Colleague_B) {
            mediators.put("colleague_B", colleague);
        }
    }
    //中介获取到 租客A 与 租客 B 的信息后,进行智能分析,并给出以下结论
    @Override
    public void getMessage(Colleague colleague) {
        //当为组合A 调用中介时,中介将租客 B 的需求进行返回 ,表示可以合租
        //这里就是中介的作用,将租客A与租客B进行关联,之间的业务逻辑都在中介中实现,将A与B彻底解耦,便于扩展维护
        if(colleague instanceof Colleague_A) {
            //智能分析A需求
            handler(colleague.needs());
            //调用租客A的需求
            System.out.println("服务的当前对象为====租客A=====");
            System.out.println("租客A 你的需求与 租客B 相吻合,下面将为你展示租客B的需求");
            String need_B = mediators.get("colleague_B").needs();
            System.out.println(need_B);
        }else if(colleague instanceof Colleague_B) {
            //智能分析B需求
            handler(colleague.needs());
            //调用租客B的需求
            System.out.println("服务的当前对象为====租客B=====");
            System.out.println("租客B 你的需求与 租客A 相吻合,下面将为你展示租客A的需求");
            String need_A = mediators.get("colleague_A").needs();
            System.out.println(need_A);
        }
    }
    //通过人工智能对用户需求进行分析 , 非设计模式的重点,省略
    private void handler(String needs) {
 
    }
}
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

【3】抽象同事类(Colleague)角色: 租客对象的抽象接口,将租客的共同点抽取。sendMessage 方法是通过调用中介的 getMessage 方法进行业务逻辑处理,返回符合用户需求的房屋信息或房客信息。needs 则为用户的需求。

public interface Colleague {
    //租客发出需求
    public void sendMessage();
    //需求方法
    public String needs();
}
1
2
3
4
5
6

【4】具体同事类(Concrete Colleague)角色: 租客的具体信息,我们距离用创建了两个租客A与B,实现租客接口 Colleague 并调用中介的业务逻辑处理方法 getMessage 进行房屋信息匹配。如下:租客A

public class Colleague_A implements Colleague{
    private Mediator mediator;
    //组合中介类
    public Colleague_A(Mediator mediator) {
        this.mediator = mediator;
        //将 租房 客户 A 注册到中介中
        mediator.register(this);
    }
    //租客A 发送自己的需求
    @Override
    public void sendMessage() {
        mediator.getMessage(this);
    }
    public String needs() {
        return "需要租两室一厅,本人女,找一名合租者";
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

【5】租客B

public class Colleague_B implements Colleague{
    //组合中介类
    private Mediator mediator;
 
    //将租客B 注册到中介类中
    public Colleague_B(Mediator mediator) {
        this.mediator = mediator;
        mediator.register(this);
    }
    //租客B 发送自己的需求
    @Override
    public void sendMessage() {
        mediator.getMessage(this);
    }
    public String needs() {
        return "需要一套两室一厅,需要一名女士合租";
    }
}​​
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(adsbygoogle = window.adsbygoogle || []).push({});