一、什么是中介者模式
中介者模式是一种行为型设计模式,它用于减少对象之间互相通信的复杂性。中介者模式通过创建一个中介者对象,将对象之间的通信集中交给该对象来处理,而不是直接相互交流,是符合迪米特原则的典型应用。
迪米特原则:减少对象之间的依赖,即一个对象应当对其它对象有尽可能少的了解
二、角色组成
抽象中介者(Mediator):用于协调各个同事对象之间交互的通用接口,如接收和发送消息等。 具体中介者(Concrete
Mediator):实现抽象中介者接口,定义一个List来管理同时对象,协调各个同事对象之间的交互,依赖于同事角色。
抽象同事类(Colleague):保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
具体同事类(Concrete
Colleague):实现抽象同事类接口,当需要与其他同事对象交互时,由中介者对象负责后续的交互,简单地说就是维护和中介者对象的通信。
三、优缺点
优点:
减少对象之间的耦合度,使其变得简单易维护。
提高代码的重用性和可扩展性,增强了系统的灵活性和可维护性。
降低了类的复杂度,将一对多转化成了一对一。
缺点:
中介者对象通常具有较高的复杂性,难以实现。
当对象之间的交互较少或简单时,中介者模式可能会增加系统的一些不必要的复杂性。
随着系统的扩大,中介者模式的复杂度可能会增加,使得代码难以维护。
四、应用场景
4.1 生活场景
物流公司:通常作为中介者来协调包裹和货物的运输、仓储和投递等工作,同时保证货物的质量和安全,提高物流效率和服务水平。
某宝:管理各个商家和用户之间的交易信息,负责物流、支付等方面的处理,同时收取一定的手续费。
论坛和社交网络:处理用户之间的交流、分享和反馈等信息,同时处理违规信息和言论。
eg:只要是需要协调各方之间的合作和交互的领域,都有可能会涉及到中介者模式。
4.2 java场景
MVC架构:MVC架构中的控制器(Controller)部分,负责协调模型(Model)和视图(View)之间的交互。
SPring:Spring框架中的事件机制和发布/订阅模式,通过应用程序上下文(Application
Context)作为中介者,不同的组件可以通过事件监听器和发布者-订阅者模式进行交互。
消息队列:消息队列是一个典型的使用中介者模式的例子,消息队列系统中的中介者负责接收、存储和分发消息。
五、代码实现
下面以物流公司协调运输公司和商家为例,解释一下中介者模式。 在物流公司中,中介者是一个"物流中心",表示用于协调和管理各个参与方(运输公司、客户等)之间的交互关系。
5.0 UML类图
5.1 抽象中介者(Mediator)------LogisticsCenter
java
/**
*
* 1.抽象中介者(Mediator):物流中心
* 定义:用于协调各个同事对象之间交互的通用接口
*/
public interface LogisticsCenter {
// 参与方注册方法,用于新增参与方
void register(Participant participant);
// 发送信息方法,用于同事之间的信息传递
void send(String from, String to, String message);
}
5.2 抽象同事类(Colleague)------Participant
java
/**
*
* 2.抽象同事类(Colleague):参与者(同事)
* 定义:保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
*/
public abstract class Participant {
// 中介者对象
protected final LogisticsCenter logisticsCenter;
public Participant(LogisticsCenter logisticsCenter) {
this.logisticsCenter = logisticsCenter;
}
// 消息发送方法,根据传递给中介者
public abstract void send(String to, String message);
// 消息接收方法,由中介者调用
public abstract void receive(String message);
}
5.3 具体同事类(Concrete Colleague)------TransportCompany&Merchant
java
/**
*
* 3.具体同事类(Concrete Colleague):运输公司
* 定义:实现抽象同事类接口,当需要与其他同事对象交互时,
* 由中介者对象负责后续的交互,简单地说就是维护和中介者对象的通信。
*/
public class TransportCompany extends Participant{
public TransportCompany(LogisticsCenter logisticsCenter) {
super(logisticsCenter);
}
// 消息发送方法的实现,发送信息给中介者对象
@Override
public void send(String to, String message) {
logisticsCenter.send("运输公司", to, message);
}
// 消息接收方法的实现,打印接收信息的内容
@Override
public void receive(String message) {
System.out.println("运输公司接到消息: " + message);
}
}
/**
*
* 3.具体同事类(Concrete Colleague):商家
* 定义:实现抽象同事类接口,当需要与其他同事对象交互时,
* 由中介者对象负责后续的交互,简单地说就是维护和中介者对象的通信。
*/
public class Merchant extends Participant{
public Merchant(LogisticsCenter logisticsCenter) {
super(logisticsCenter);
}
// 消息发送方法的实现,发送信息给中介者对象
@Override
public void send(String to, String message) {
logisticsCenter.send("商家", to, message);
}
// 消息接收方法的实现,打印接收信息的内容
@Override
public void receive(String message) {
System.out.println("商家接收到消息: " + message);
}
}
5.4 具体中介者(Concrete Mediator)------LogisticsCenterImpl
java
/**
*
* 4.具体中介者(Concrete Mediator):物流公司
* 定义:实现抽象中介者接口,定义一个List来管理同时对象,
* 协调各个同事对象之间的交互,依赖于同事角色。
*/
public class LogisticsCenterImpl implements LogisticsCenter{
// 参与方列表,用于管理同事之间的交互关系
private final Map<String, Participant> participants = new HashMap<>();
// 参与方注册方法的实现,向同事列表中添加参与方
@Override
public void register(Participant participant) {
participants.put(participant.getClass().getSimpleName(), participant);
}
// 发送信息方法的实现,根据接收方信息调用接收方的消息接收方法
@Override
public void send(String from, String to, String message) {
Participant participant = participants.get(to);
if (participant != null) {
participant.receive("Message from " + from + ": " + message);
}
}
}
5.5 testMediator
java
/**
*
* 中介者模式测试类
*/
@SpringBootTest
public class TestMediator {
@Test
void testMediator(){
//创建物流中心对象
LogisticsCenter logisticsCenter = new LogisticsCenterImpl();
//运输公司
TransportCompany company = new TransportCompany(logisticsCenter);
//商家
Merchant merchant = new Merchant(logisticsCenter);
//都注册到物流中心
logisticsCenter.register(company);
logisticsCenter.register(merchant);
//发送消息给物流公司(中介者)
company.send("Merchant", "快递已送达");
merchant.send("TransportCompany", "收到,幸苦了");
}
}
六、总结
当出现以下情况,可以考虑使用中介者模式:
如果对象之间的交互关系复杂且难以维护,或者对象之间需要大量的相互调用和信息传递,可以考虑使用中介者模式来简化对象之间的通信和协调。
如果对象之间紧密耦合,修改一个对象可能会影响到其他相关对象,使得系统难以进行扩展和维护。使用中介者模式可以降低对象之间的耦合度,使得对象可以独立变化和复用。
当系统中存在一个有组织结构的集合,并且该集合中的对象之间需要相互通信和协作时。比如,一个群聊系统中的参与者之间需要进行信息传递和交流,此时可以使用中介者模式来管理参与者之间的通信。
当需要集中化管理和控制一些公共行为或操作时。中介者模式可以充当一个中心协调者,负责管理和调度相关对象的行为或操作。例如,在一个电梯控制系统中,电梯调度器扮演中介者的角色,控制电梯的运行和调度。
总结一下,中介者模式可以有效地降低对象之间的耦合度,简化对象之间的交互。适用于对象之间的关系非常复杂,需要协调处理的情况,从而提高代码的可维护性和可扩展性。但是,如果应用不当,可能会使得系统的复杂度增加,不利于代码的维护和扩展。因此,在使用中介者模式时需要掌握适当的使用场景。