中介者模式
# 中介者模式
# 定义
用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
从类图中看,中介者模式由以下几部分组成:
Mediator 抽象中介者角色
抽象中介者角色定义统一的接口,用于各同事角色之间的通信。
Concrete Mediator 具体中介者角色
具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
Colleague 抽象同事类
定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分为两种:一种是同事本身的行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为(Self-Method),与其他的同事类或中介者没有任何的依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法(Dep-Method)。
Concrete Colleague 同事角色
抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
# 核心思想
如果一个系统中对象之间的联系呈现出网状结构,对象之间存在大量多对多关系,将导致关系及其复杂,这些对象称为 "同事对象"。我们可以引入一个中介者对象,使各个同事对象只跟中介者对象打交道,将同事对象之间的关系行为进行分离和封装,使之成为一个松耦合的系统。
# 本质
解耦各个同事对象之间的交互关系。每个对象都持有中介者对象的引用,只跟中介者对象打交道。通过中介者对象统一管理这些交互关系,并且还可以在同事对象的逻辑上封装自己的逻辑。
# 实现简单的中介者模式
模拟同事之间发送、接收消息
每一个同事角色都知道中介者角色,而且与其它的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分两种:一种是同事本身行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为,与其它同事类或者中介者没有任何依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法。
/**
* 抽象同事类
* @version 1.0.0
* @date 2021/11/25 17:31
*/
public abstract class Colleague {
protected Mediator mediator;
public void setMedium(Mediator mediator) {
this.mediator = mediator;
}
public abstract void receive();
public abstract void send();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
抽象中介者角色定义统一的接口,用于各同事角色之间的通信。
/**
* 抽象中介者
* @version 1.0.0
* @date 2021/11/25 17:30
*/
public abstract class Mediator {
public abstract void register(Colleague colleague);
public abstract void relay(Colleague colleague);
}
2
3
4
5
6
7
8
9
10
11
12
具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
/**
* 具体中介者
* @version 1.0.0
* @date 2021/11/25 17:46
*/
public class ConcreteMediator extends Mediator{
private List<Colleague> colleagues = new ArrayList<Colleague>();
@Override
public void register(Colleague colleague) {
if (!colleagues.contains(colleague)) {
colleagues.add(colleague);
colleague.setMedium(this);
}
}
@Override
public void relay(Colleague cl) {
for (Colleague ob : colleagues) {
if (!ob.equals(cl)) {
ob.receive();
}
}
}
}
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
同事类必须有中介者,而中介者却可以只有部分同事类。
/**
* 具体同事1
* @version 1.0.0
* @date 2021/11/25 17:37
*/
public class ConcreteColleague1 extends Colleague{
@Override
public void receive() {
System.out.println("具体同事类1收到请求。");
}
@Override
public void send() {
System.out.println("具体同事类1发出请求。");
//请中介者转发
mediator.relay(this);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 具体同事2
* @version 1.0.0
* @date 2021/11/25 18:00
*/
public class ConcreteColleague2 extends Colleague{
@Override
public void receive() {
System.out.println("具体同事类2收到请求。");
}
@Override
public void send() {
System.out.println("具体同事类2发出请求。");
//请中介者转发
mediator.relay(this);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
输出结果
具体同事类1发出请求。
具体同事类2收到请求。
具体同事类2发出请求。 具体同事类1收到请求。
# 应用场景
- 何时使用
- 多个类相互耦合,形成网状结构时
- 方法
将网状结构分离为星型结构
系统中对象之间存在比较复杂的引用关系
想通过一个中间类来封装多个类的行为,而又不想生成太多的子类
# 优点
中介者模式的优点就是减少类间的依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减少了依赖,当然同时也降低了类间的耦合。类之间各司其职,符合迪米特法则
# 缺点
中介者模式的缺点就是中介者会膨胀得很大,而且逻辑复杂,原本N个对象直接的相互依赖关系转换为中介者和同事类的依赖关系,同事类越多,中介者的逻辑就越复杂。
# 应用
/**
* 抽象中介者
*/
public interface Mediator {
void register(String dname,Department d);
void command(String dname);
}
2
3
4
5
6
7
8
9
/**
* 抽象同事类
*/
public interface Department {
// 做本部门的事情
void selfAction();
// 向总经理发出申请
void outAction();
}
2
3
4
5
6
7
8
9
10
/**
* 具体中介者 总经理
*/
public class President implements Mediator{
private Map<String,Department> map = new HashMap <String , Department>();
@Override
public void command(String dname) {
// 在不改变同事类的情况下,封装一些公共的逻辑
System.out.println("执行前-----打印日志信息");
map.get(dname).selfAction();
System.out.println("执行后-----打印日志信息");
}
@Override
public void register(String dname, Department d) {
map.put(dname, d);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 具体同事类 财务
*/
public class Finacial implements Department {
// 持有中介者(总经理)的引用
private Mediator m;
public Finacial(Mediator m) {
super();
this.m = m;
m.register("finacial", this);
}
@Override
public void outAction() {
System.out.println("汇报工作!没钱了");
}
@Override
public void selfAction() {
System.out.println("管理财务");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 具体同事类 市场部
*/
public class Market implements Department {
// 持有中介者(总经理)的引用
private Mediator m;
public Market(Mediator m) {
super();
this.m = m;
m.register("market", this);
}
@Override
public void outAction() {
System.out.println("汇报项目承接的进度,需要资金支持");
// 通过中介者调用同事类,并没有和同事类耦合。
m.command("finacial");
}
@Override
public void selfAction() {
System.out.println("谈项目");
}
}
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) {
Mediator m = new President();
Market market = new Market(m);
Finacial f = new Finacial(m);
market.selfAction();
market.outAction();
}
}
2
3
4
5
6
7
8
9
10
11
12
输出结果
谈项目 汇报项目承接的进度,需要资金支持 执行前-----打印日志信息 管理财务 执行后-----打印日志信息
# 总结
中介者模式其实就是将一个复杂的事分离出来统一管理,将同事对象之间的关系行为进行分离和封装。