中介者模式(作用,原理、怎么用、优缺点)
目录
一、为什么要用中介者模式
中介者模式核心在于中介者这个角色,理解上可以参考现实中的中介者,中介就跟中间人一样,跟桥梁一样。比方说你到了个陌生的城市,要找工作,要找房子。如果一个人冒冒失失的盲目的找,不仅花费的时间跟精力非常大,即使找到了也不是理想中的。这时候中介就发挥作用了。它会根据你的要求,帮你安排那样的工作适合你,跟用人方取得联系。
代码的世界里,如果各个类之间互相依赖,每个类内部引入其他类,当类增多时就会形成网状依赖关系(下图左),这时代码的耦合度就很高;中介者模式可以很好的解耦这种依赖关系,所有类都只和中介者有关联,形成一种星状结构(下图右),通过中介者建立联系,而彼此不需要知道对方是谁,彼此独立,耦合性很低。
说道这你肯定想起了Spring, Spring的一个主要功能就是IOC,各层间、层内不同对象也是不需要事先注入绑定,而是将创建bean的事情全交给Spring处理,Spring负责各方的联系。
中介者模式是迪米特原则的经典体现:迪米特法则(Law of Demeter)又叫作最少知识原则(Least Knowledge Principle 简写LKP),它要求一个对象应该对其他对象保持最少的了解。如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
二、中介者模式中的角色
中介者模式涉及到的角色有四个:
- 抽象中介者角色:抽象中介者角色定义统一的接口,以及一个或者多个事件方法,用于各同事角色之间的通信。
- 具体中介者角色:实现了抽象中介者所声明的事件方法,协调各同事类之间的行为,持有所有同事类对象的引用。
- 抽象同事类角色:定义了抽象同事类,持有抽象中介者对象的引用。
- 具体同事类角色:继承抽象同事类,实现自己业务,通过中介者跟其他同事类进行通信。
三、中介者模式怎么用?
我们实现下面的一个实例:
比如模拟李云龙打仗。李云龙现在要去打鬼子的伏击抢点弹药回来,手底下有3个营,鬼子装备精良,这三个营之间只有互相配合才有胜算。那李云龙就是指挥官(中介者),三个营(同事类)完成各自任务,相互间通信配合都通过李云龙。
抽象中介者:
public interface Mediator {
// 各营在这里注册,接收各营发来的战况电报
void receive(String name, Colleague colleague);
// 下达命令
void order(String name);
}
抽象同事类:
public interface Colleague {
void battle();
void teamWork();
}
具体同事类:一营
/**
* Feng, Ge 2020/3/10 0010 15:02
*/
public class FirstCamp implements Colleague {
private Mediator mediator;
public FirstCamp(Mediator mediator) {
this.mediator = mediator;
mediator.receive("一营", this);
}
@Override
public void battle() {
System.out.println("一营要正面进攻了!");
}
@Override
public void teamWork() {
System.out.println("报告营长,一营任务正面扛不住了,请求李团长派三营接应!");
mediator.order("三营");
}
}
具体同事类:二营
/**
* Feng, Ge 2020/3/10 0010 15:02
*/
public class SecondCamp implements Colleague {
private Mediator mediator;
public SecondCamp(Mediator mediator) {
this.mediator = mediator;
mediator.receive("二营", this);
}
@Override
public void battle() {
System.out.println("二营要侧面进攻了!");
}
@Override
public void teamWork() {
System.out.println("报告营长,二营侧面进攻有些压力,需要一营正面加强火力掩护!");
mediator.order("一营");
}
}
具体同事类:三营
/**
* Feng, Ge 2020/3/10 0010 15:03
*/
public class ThirdCamp implements Colleague {
private Mediator mediator;
public ThirdCamp(Mediator mediator) {
this.mediator = mediator;
mediator.receive("三营", this);
}
@Override
public void battle() {
System.out.println("三营在外围接应!");
}
@Override
public void teamWork() {
System.out.println("报告营长,三营任务已完成,请指示!");
}
}
具体中介者: 李云龙
/**
* Feng, Ge 2020/3/10 0010 14:51
*/
public class YunLongLi implements Mediator {
private Map<String,Colleague> map = new HashMap<String , Colleague>();
@Override
public void receive(String name, Colleague colleague) {
map.put(name, colleague);
}
@Override
public void order(String name) {
map.get(name).battle();
}
}
测试类:
/**
* Feng, Ge 2020/3/10 0010 15:49
*/
public class MdiatorTest {
public static void main(String[] args) {
Mediator mediator = new YunLongLi();
FirstCamp firstCamp = new FirstCamp(mediator);
SecondCamp secondCamp = new SecondCamp(mediator);
ThirdCamp thirdCamp = new ThirdCamp(mediator);
firstCamp.battle();
firstCamp.teamWork();
System.out.println("====================================");
secondCamp.battle();
secondCamp.teamWork();
System.out.println("====================================");
thirdCamp.battle();
thirdCamp.teamWork();
System.out.println("把老子的意大利炮来出来,轰他娘的小鬼子,秀琴对不住了,开炮!!!!!");
}
}
结果:
一营要正面进攻了!
报告营长,一营任务正面扛不住了,请求李团长派三营接应!
三营在外围接应!
====================================
二营要侧面进攻了!
报告营长,二营侧面进攻有些压力,需要一营正面加强火力掩护!
一营要正面进攻了!
====================================
三营在外围接应!
报告营长,三营任务已完成,请指示!
把老子的意大利炮来出来,轰他娘的小鬼子,秀琴对不住了,开炮!!!!!
以上,各营的行动彼此需要支援的时候,例如一营需要三营外围接应的时候,不是一营长和三营长直接对话,而是通过李云龙,李云龙根据name去调用具体的map.get(name).battle()方法。
四、中介者模式的优缺点
优点
1)解耦。把同事类原来一对多的依赖变成一对一的依赖,降低同事类的耦合度,同时也符合了迪米特原则。
缺点
1)中介者模式把业务流程和协调都写在中介者,当同事类越多,中介者的业务就越复杂,造成不好管理的弊端。
五、使用场景
中介者模式很容易实现呢,但是也容易误用,不要着急使用,先要思考你的设计是否合理。
当对象之间的交互变多时,为了防止一个类会涉及修改其他类的行为,可以使用中介者模式,将系统从网状结构变为以中介者为中心的星型结构。
中介者模式和代理模式的区别:
代理模式是结构型设计模式,它有很多种类型,主要是在访问对象时引入一定程度的间接性,由于有间接性,就可以附加多种的用途,比如进行权限控制。中介者模式则是为了减少对象之间的相互耦合。
外观模式和中介者模式:
外观模式主要是以封装和隔离为主要任务,中介者则是调停同事类之间的关系,因此,中介者具有部分业务的逻辑控制。他们之间的主要区别为:
- 外观模式的子系统如果脱离外观模式还是可以运行的,而中介者模式增加了业务逻辑,同事类不能脱离中介者而独自存在。
- 外观模式中,子系统是不知道外观类的存在的,而中介者模式中,每个同事类都知道中介者。
- 外观模式将子系统的逻辑隐藏,用户不知道子系统的存在,而中介者模式中,用户知道同事类的存在。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!