【设计模式】中介者模式(行为设计模式)
对于中介者,任谁一听都想到了房产中介,然而房产中介的职责和这个中介者模式的职责很类似,就是在买房和卖房之间建立一个桥梁通讯(当然了,我们这个不收费O(∩_∩)O)
中介者模式的意图
中介者使各个对象之间不需要显示的相互引用,而是通过一个比较特殊的中介对象使得程序组件间进行通讯,以此来实现介绍程序组件之间的耦合。(看到这里,我想到了Vue里面的Vuex)
这个模式会限制对象之间进行直接通讯,通过中介对象来协作(想一下,后端好像MVC模式中的Controller部分????!!!!!好特么像)
具体来说,中介者模式的意图就在于:减少对象之间的混乱关系(那些让人分不清的多对多的关系)时,通过中介者进行统一管理这些对象,将对象之间的交互封装在中介者的对象里面。(一下子懵逼了??????好像没啥用,又好像有大用,到底会给我们解决什么困难?)
解决了什么问题
- 比如我们进行聊天,用户与用户之间一定存在多对多的关系,这时候我们可以使用一个中介者(咱们的群聊)来进行统一管理,用户只需要将信息或文件发送到群里面或者上传就行,这样用户就不需要一个一个用户发送了(这是一个比较传统的问题)
- 还有一个我们熟悉的开发问题,当然现在好像都需要这个意识。。。:一个开发中,基本上每个对象都会与其他对象发送相互作用,我们一旦引入新对象,系统的结构又要复杂很多倍,这时候我们通常会设置中介者对象,这样对象与对象之间就不会直接进行联系,而是通过中介者进行联系。
说白了,中介者就是为了解决“依赖关系结构混乱”问题
看到这里,基本上都理解了,这时候我们可以看看中介者模式大概如何实现了!
结构图(找的一张图不要介意。。)
应用实例
采用中介模式来说明联合国的作用,联合国实际上是一个协调性组织,各个成员国之间有下属机构WTO、WFC、WHO,他们作为各个成员国家之间的事务协调者,采用中介模式来设计该模拟系统。
抽象中介者(Mediator)角色
/**
* @Description 联合国
*/
public interface UN {
/**
* 该国家在联合国进行注册
* @param country 国家
*/
public void register(Country country);
/**
* 对联合国进行事务发送请求
* @param from 发送国
* @param to 接受国
* @param message 信息(这里我们只用大概来形容)
*/
public void sendNegotiate(String from, String to, String message);
}
具体中介者(ConcreteMediator)角色:维护同事的交互关系
联合国下属机构
/**
* @Description 联合国下属机构
*/
public class WFC implements UN{
private Map<String, Country> countrys = new HashMap<>();
@Override
public void register(Country country) {
// 检查是否已经存在过该国家
if(!countrys.containsValue(country)) {
countrys.put(country.getName(), country);
}
// country.setUn(this);
}
@Override
public void sendNegotiate(String from, String to, String message) {
Country country = countrys.get(from);
if(country != null) {
// 这里可以进行违禁字检查
System.out.println(from + "发送信息给" + to + ":" + message);
country.receiveNegotiate(to, message);
}
}
}
/**
* @Description 联合国下属机构
*/
public class WHO implements UN{
private Map<String, Country> countrys = new HashMap<>();
@Override
public void register(Country country) {
// 检查是否已经存在过该国家
if(!countrys.containsValue(country)) {
countrys.put(country.getName(), country);
}
country.setUn(this);
}
@Override
public void sendNegotiate(String from, String to, String message) {
Country country = countrys.get(from);
if(country != null) {
// 这里可以进行违禁字检查
System.out.println(from + "发送信息给" + to + ":" + message);
country.receiveNegotiate(to, message);
}
}
}
/**
* @Description 联合国下属机构
*/
public class WTO implements UN{
private Map<String, Country> countrys = new HashMap<>();
@Override
public void register(Country country) {
// 检查是否已经存在过该国家
if(!countrys.containsValue(country)) {
countrys.put(country.getName(), country);
}
// country.setUn(this);
}
@Override
public void sendNegotiate(String from, String to, String message) {
Country country = countrys.get(from);
if(country != null) {
// 这里可以进行违禁字检查
System.out.println(from + "发送信息给" + to + ":" + message);
country.receiveNegotiate(to, message);
}
}
}
抽象同事类(Colleague)角色
/**
* @Description
*/
public abstract class Country {
public UN un;
public String name;
public Country(String name) {
this.name = name;
}
public UN getUn() {
return un;
}
public void setUn(UN un) {
this.un = un;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void sendNegotiate(String to, String message);
public void receiveNegotiate(String to, String message) {
System.out.println(to + "接收到" + this.name + "发送的信息:" + message);
}
}
具体同事类(Concrete Colleague)角色
/**
* @Description
*/
public class DevelopedCoun extends Country{
public DevelopedCoun(String name) {
super(name);
}
@Override
public void sendNegotiate(String to, String message) {
if(un != null) {
un.sendNegotiate(this.name, to, message);
}else {
System.out.println(this.name + "未加入" + to + ", 不能通过该组织发送消息");
}
}
}
/**
* @Description
*/
public class DevelopingCoun extends Country{
public DevelopingCoun(String name) {
super(name);
}
@Override
public void sendNegotiate(String to, String message) {
if(un != null) {
un.sendNegotiate(this.name, to, message);
}else {
System.out.println(this.name + "未加入" + to + ", 不能通过该组织发送消息");
}
}
}
实现类
/**
* @author haoyang
* @create 2022-11-04 18:52
* @Description
*/
public class Client {
public static void main(String[] args) {
// 设立机构
UN un1 = new WFC();
UN un2 = new WHO();
UN un3 = new WTO();
// 建立国家
Country china, usa;
// 设置国家类别
china = new DevelopingCoun("中国");
usa = new DevelopedCoun("美国");
// 在该机构注册国家
un1.register(china);
un2.register(china);
un3.register(china);
un1.register(usa);
un2.register(usa);
un3.register(usa);
// 发送信息
china.sendNegotiate(usa.getName(), "你个傻逼");
}
}
优缺点
优点
- 简化了对象之间的交互,降低了类的复杂度,将一对多转换为一对一
- 可将各同事对象解耦
- 减少子类生成,中介者模式将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使得各个同事类可被重用,无需直接对同事类进行扩展
缺点
- 具体中介者中包含了大量同事之间的交互细节,中介者可能会变得非常复杂庞大,可能会难以维护。
使用时注意点
1、减少类间依赖,降低了耦合,符合迪米特法则
2、多个类相互解耦,会形成网状结构,使用中介者模式将网状结构分离为星型结构,进行解耦
3、如果设计不当,中介者对象本身变得过于复杂,这点在实际使用时,要特别注意
4、中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响
适用场景
1、对象之间存在复杂的引用关系,导致他们之间的依赖关系结构混乱而且难以复用该对象。
2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
3、一个对象由于引用了其他很多对象并且直接和这些对象进行通信,导致了难以复用该对象