一、什么是中介者模式
中介者模式是一种行为型设计模式,它用于减少对象之间互相通信的复杂性。中介者模式通过创建一个中介者对象,将对象之间的通信集中交给该对象来处理,而不是直接相互交流,就是用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。是符合迪米特原则的典型应用。
迪米特原则:减少对象之间的依赖,即一个对象应当对其它对象有尽可能少的了解
二、优缺点
优点:
- 减少对象之间的耦合度,使其变得简单易维护。
- 提高代码的重用性和可扩展性,增强了系统的灵活性和可维护性。
- 降低了类的复杂度,将一对多转化成了一对一。
缺点:
- 中介者对象通常具有较高的复杂性,难以实现。
- 当对象之间的交互较少或简单时,中介者模式可能会增加系统的一些不必要的复杂性。
- 随着系统的扩大,中介者模式的复杂度可能会增加,使得代码难以维护。
三、应用场景
1.生活场景
- 物流公司:通常作为中介者来协调包裹和货物的运输、仓储和投递等工作,同时保证货物的质量和安全,提高物流效率和服务水平。
- 某宝:管理各个商家和用户之间的交易信息,负责物流、支付等方面的处理,同时收取一定的手续费。
- 论坛和社交网络:处理用户之间的交流、分享和反馈等信息,同时处理违规信息和言论。
- 联合国/WTO作为中介者协调各个国家
eg:只要是需要协调各方之间的合作和交互的领域,都有可能会涉及到中介者模式。
2.java场景
- MVC架构:MVC架构中的控制器(Controller)部分,负责协调模型(Model)和视图(View)之间的交互。
- Spring:Spring框架中的事件机制和发布/订阅模式,通过应用程序上下文(Application Context)作为中介者,不同的组件可以通过事件监听器和发布者-订阅者模式进行交互。
- 消息队列:消息队列是一个典型的使用中介者模式的例子,消息队列系统中的中介者负责接收、存储和分发消息。
四、代码实现
上面我们有提到,联合国作为一个由各国代表组成,用来维护国际和平与安全,解决国际间经济、社会、文化和人道主义性质的问题的角色,它就是一个调停者、中介者的角色,国与国直接完全完全可以通过“联合国”这个中介者来发生关系,而不用直接通信。
下面就以联合国安理会作为中介者,了解一下中介者模式。
1. 联合国机构
抽象中介者。
抽象类UnitedNations
包含一个公共的抽象方法:
这个方法声明了一个接口,表明任何继承UnitedNations
的具体子类都必须提供自己的实现版本。方法接受两个参数:
String message
: 表示要宣告或传达的信息内容
Country country
: 表示与该宣告相关的国家对象实例
public abstract class UnitedNations {
//公共的抽象方法
public abstract void declare(String message, Country country);
}
2. 国家类
抽象国家类,需声明中介者角色。
Country
的类,表示一个国家,在这个类中,每个国家实例都有与联合国(UnitedNations
)的关联关系
类中的构造函数接收一个UnitedNations
类型的参数,在创建Country
实例时需要传入一个UnitedNations
对象。通过这种方式,每个国家实例在初始化时就与特定的联合国实例建立了联系,从而可以在后续的操作中通过这个引用调用联合国的相关方法,比如之前提到的declare
方法来宣告消息
public class Country {
protected UnitedNations unitedNations;
public Country(UnitedNations unitedNations) {
this.unitedNations = unitedNations;
}
}
3. 具体国家类
具体国家类,继承了抽象国家类。这里以USA类和Iraq类举例
构造函数:接受一个UnitedNations
类型的参数,调用了父类Country
的构造函数,将传递进来的联合国实例赋值给父类中的unitedNations
属性。这样,美国实例就可以通过这个引用与联合国进行交互
declare() 方法:这个方法实现了美国向联合国宣告消息的功能。当美国需要对外宣告一条消息时,它调用联合国的declare
方法,将消息内容message
以及自身作为参数传递给联合国,由联合国负责协调和传播这条消息到其他相关国家或组织。
getMessage() 方法:这个方法展示了美国接收到其他国家或联合国传达过来的信息时的行为。当有消息传递给美国时,该方法会被调用,并将接收到的消息打印到控制台
public class USA extends Country {
public USA(UnitedNations unitedNations) {
super(unitedNations);
}
public void declare(String message) {
unitedNations.declare(message, this);
}
public void getMessage(String message) {
System.out.println("美国获得对方信息:" + message);
}
}
public class Iraq extends Country{
public Iraq(UnitedNations unitedNations) {
super(unitedNations);
}
public void declare(String message) {
unitedNations.declare(message, this);
}
public void getMessage(String message) {
System.out.println("伊拉克获得对方信息:" + message);
}
}
4. 联合国安理会
具体中介者角色,继承抽象中介者,重写其declare()方法,对不同国家发送不同信息。
UnitedNations
抽象类的子类,特指联合国安全理事会。这个类有两个私有成员变量usa
和iraq
,分别代表美国和伊拉克两个国家实例
重写declare()方法:
这个方法覆盖了UnitedNations
抽象类中的declare
方法。在本实现中,如果传入的country
参数是美国实例,则将消息直接发送给伊拉克(通过调用iraq.getMessage(message)
);反之,则将消息发送给美国(通过调用usa.getMessage(message)
)。
public class UnitedNationsSecurityCouncil extends UnitedNations {
private USA usa;
private Iraq iraq;
public void setUsa(USA usa) {
this.usa = usa;
}
public void setIraq(Iraq iraq) {
this.iraq = iraq;
}
@Override
public void declare(String message, Country country) {
if(country == usa) {
iraq.getMessage(message);
} else {
usa.getMessage(message);
}
}
}
5. Client客户端
实例化一个联合国安理会对象,两国通过联合国安理会进行对话。
public class Client {
public static void main(String[] args) {
// 创建联合国安全理事会实例
UnitedNationsSecurityCouncil UNSC = new UnitedNationsSecurityCouncil();
// 创建美国和伊拉克实例,并将联合国安全理事会实例注入到各自的构造函数中
USA usa = new USA(UNSC);
Iraq iraq = new Iraq(UNSC);
// 设置联合国安全理事会中的美国和伊拉克成员
UNSC.setUsa(usa);
UNSC.setIraq(iraq);
// 模拟美国向联合国安全理事会宣告信息
usa.declare("不准研制核武器");
// 模拟伊拉克向联合国安全理事会宣告信息
iraq.declare("我们没有核武器");
}
}
运行结果如下: