中介模式
# 中介模式
中介模式通过引入一个中介对象,将对象之间的通信逻辑集中管理,实现了对象之间的松耦合和灵活的交互。它是一种有助于组织复杂交互的设计模式,提供了更好的可维护性和可扩展性。
# 定义
中介模式(Mediator Pattern)是一种行为设计模式,它通过引入一个中介对象来协调多个对象之间的交互。中介对象封装了对象之间的通信逻辑,使得对象之间的交互变得松耦合,减少了对象之间的直接依赖关系。
# 结构
抽象中介者(Abstract Mediator):抽象中介者定义了中介者对象的接口,它通常包含了各个对象之间交互的方法。
具体中介者(Concrete Mediator):具体中介者是抽象中介者的子类,它实现了在抽象中介者中定义的方法。它负责协调各个对象之间的交互,接收来自对象的消息,并根据消息的内容进行适当的处理和转发。
抽象同事类(Abstract Colleague):抽象同事类定义了同事类的接口,它通常包含了一个指向中介者对象的引用。同事类可以是具体同事类的父类,也可以是一个接口。
具体同事类(Concrete Colleague):具体同事类是抽象同事类的子类或实现类,它实现了在抽象同事类中定义的方法。具体同事类之间相互通信时,需要通过中介者对象进行。
- img: https://bitouyun.com/images/design-pattern/mediator.png
link: https://bitouyun.com/images/design-pattern/mediator.png
name: 中介模式
2
3
# 优点
减少对象之间的直接依赖:中介模式通过引入中介对象,将对象之间的通信逻辑集中在中介对象中。这样可以降低对象之间的直接依赖,减少耦合性,使得对象之间的交互更加松散和灵活。
促进松耦合设计:中介模式将对象之间的交互抽象到中介对象中,使得每个对象只需要关注自身的职责,而不需要了解其他对象的细节。这样可以实现松耦合的设计,提高系统的可维护性和可测试性。
集中管理通信逻辑:中介模式将对象之间的通信逻辑集中在中介对象中,使得通信逻辑更加清晰和可控。中介对象负责接收和分发消息,协调对象之间的交互,避免了交互逻辑的分散和重复。
简化对象间的交互:中介模式简化了对象之间的交互方式。对象只需要通过中介对象进行通信,不需要直接与其他对象进行交互。这样可以减少对象之间的交互复杂性,使得系统更易于理解和维护。
# 缺点
中介对象的复杂性:引入中介对象可能会增加一个额外的组件,即中介对象本身。这可能会增加系统的复杂性,特别是当中介对象需要处理大量的对象和复杂的交互逻辑时。
单点故障:中介对象负责协调对象之间的交互,如果中介对象出现问题或者失败,可能会影响整个系统的功能。因此,在设计中介模式时,需要考虑中介对象的容错和可靠性。
过度集中化:如果中介对象承担了过多的责任和功能,可能导致中介对象变得庞大和复杂。这可能违反单一职责原则,使得中介对象难以维护和扩展。
通信效率降低:中介模式引入了中介对象作为通信媒介,可能会增加通信的开销和延迟。因为对象之间的交互需要经过中介对象进行转发和处理,可能会导致一定的性能损失。
# 应用场景
对象之间存在复杂的交互关系:当多个对象之间存在复杂的交互和依赖关系时,引入中介模式可以简化对象之间的通信和管理。这样可以避免对象之间的紧耦合,提高系统的灵活性和可维护性。
减少对象之间的直接依赖:中介模式可以减少对象之间的直接依赖,使得对象之间的交互通过中介对象进行。这样可以降低对象之间的耦合度,使得系统更加灵活和可扩展。
需要集中管理对象之间的通信:中介模式可以将对象之间的通信逻辑集中管理在中介对象中。这样可以提高代码的可维护性,减少重复代码,并且使得通信逻辑更加清晰和可控。
促进松耦合设计:中介模式可以帮助实现松耦合的设计,每个对象只需要关注自身的职责,而不需要了解其他对象的细节。这样可以提高系统的可维护性和可测试性。
事件驱动的系统:中介模式在事件驱动的系统中非常常见。中介对象可以作为事件的调度者,协调各个对象之间的事件处理和消息传递。
GUI 应用程序:图形用户界面(GUI)框架中常常使用中介模式来处理用户界面元素之间的交互。中介对象可以负责接收和分发用户输入、处理事件和更新界面等。
多人协作系统:在多人在线游戏、协同编辑工具等多人协作系统中,中介模式可以用于管理玩家之间的交互和通信,例如聊天、协同编辑、实时数据同步等。
# 示例代码
场景
租房中介模式的例子,租房中介(具体中介者)负责协调房东(具体同事类 HouseOwner)和租客(具体同事类 HouseTenant)之间的通信。房东和租客都通过中介发送消息,中介会将消息转发给其他人。房东和租客可以登记到中介者中,以便参与通信。
/**
* 抽象中介者
* 抽象中介者,通常声明了各个同事对象之间的通行方法。
*/
public interface Mediator {
// 登记信息
void register(Person person);
// 发布信息
void sendMessage(String message, Person sender);
}
2
3
4
5
6
7
8
9
10
11
/**
* 房屋中介
* 具体中介者,实现抽象中介者的接口,通常维护一个同事对象的集合,并负责对象之间的通行调度。
*/
public class HouseMediator implements Mediator {
private List<Person> persons;
public HouseMediator() {
persons = new ArrayList<>();
}
// 登记信息
@Override
public void register(Person person) {
persons.add(person);
}
// 发送信息
@Override
public void sendMessage(String message, Person sender) {
for (Person person : persons) {
if (person != sender) {
person.receiveMessage(message);
}
}
}
}
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
/**
* 抽象同事类
* 抽象同事类,持有一个中介者对象的引用,并定义了各个同事对象之间的通行方法。
*/
public abstract class Person {
protected String name;
protected Mediator mediator;
public Person(String name, Mediator mediator) {
this.name = name;
this.mediator = mediator;
}
// 发布信息
public abstract void send(String message);
// 接收信息
public abstract void receiveMessage(String message);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 房屋拥有者
* 具体同事类,实现了抽象同事类的接口,具体同事类之间通过中介者对象进行通行。
*/
@Slf4j
public class HouseOwner extends Person {
public HouseOwner(String name, Mediator mediator) {
super(name, mediator);
}
@Override
public void send(String message) {
log.info("房东:{},发布消息:{}", name, message);
mediator.sendMessage(message, this);
}
@Override
public void receiveMessage(String message) {
log.info("房东:{},接收消息:{}", name, message);
}
}
/**
* 租房者
* 具体同事类,实现了抽象同事类的接口,具体同事类之间通过中介者对象进行通行。
*/
@Slf4j
public class HouseTenant extends Person {
public HouseTenant(String name, Mediator mediator) {
super(name, mediator);
}
@Override
public void send(String message) {
log.info("租房者:{},发送消息:{}", name, message);
mediator.sendMessage(message, this);
}
@Override
public void receiveMessage(String message) {
log.info("租房者:{},接收消息:{}", name, message);
}
}
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
/**
* 测试类
*/
public class Client {
public static void main(String[] args) {
Mediator mediator = new HouseMediator();
Person owner1 = new HouseOwner("房东1", mediator);
Person owner2 = new HouseOwner("房东2", mediator);
Person tenant1 = new HouseTenant("租户1", mediator);
Person tenant2 = new HouseTenant("租户2", mediator);
// 登记信息
mediator.register(owner1);
mediator.register(owner2);
mediator.register(tenant1);
mediator.register(tenant2);
// 发布信息
owner1.send("我有一个办公室出租,需要的联系我");
owner2.send("我有一个房子出租,需要的联系我");
tenant1.send("我需要租一个办公室,有的联系我");
tenant2.send("我需要组一个房子,有的联系我");
}
}
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
// Make sure to add code blocks to your code group