1. 设计模式之中介者模式:让互相调用的模块之间解耦合
1.1. 介绍
中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性,属于行为型模式。
中介者模式定义了一个中介对象来封装一系列对象之间的交互。中介者使各对象之间不需要显式地相互引用,从而使其耦合松散,且可以独立地改变它们之间的交互。
在实际企业开发中,很难见到,单独封装一个中介者。该模式本质就是为了解耦各个系统,最常见的方式就是,系统间调用,不走直接接口调用,通过 MQ 来进行解耦。(eg:A 系统发送 MQ 消息,B 系统 和 C 系统 消费 MQ 消息,然后分别执行自己的逻辑)
1.2. 优缺点及建议
优点
- 降低复杂度:将多个对象间的一对多关系转换为一对一关系。
- 解耦:对象之间不再直接引用,通过中介者进行交互。
- 符合迪米特原则:对象只需知道中介者,不需要知道其他对象。同事类只需关注自身业务。
- 集中控制交互逻辑:便于维护和扩展新行为。
缺点
- 中介者复杂性:中介者可能会变得庞大和复杂,难以维护。
- 性能开销:所有通信需经中介者中转。
- 过度设计风险:简单交互场景不适用。
使用建议
- 当系统中对象间存在复杂的引用关系时,考虑使用中介者模式。
- 通过中介者封装多个类的行为,避免生成过多的子类。
注意事项
- 避免在职责不明确或混乱的情况下使用中介者模式,这可能导致中介者承担过多职责。
1.3. 实现及相关代码
假设有三个系统 A、B、C,他们需要相互调用。
1.3.1. 没使用设计模式方式
接口及数据对象
public static class ModuleA {
public void execute() {
ModuleB moduleB = new ModuleB();
ModuleC moduleC = new ModuleC();
moduleB.execute("模块A");
moduleC.execute("模块A");
}
public void execute(String invoker) {
System.out.println(invoker + "在调用模块A的功能");
}
}
public static class ModuleB {
public void execute() {
ModuleA moduleA = new ModuleA();
ModuleC moduleC = new ModuleC();
moduleA.execute("模块B");
moduleC.execute("模块B");
}
public void execute(String invoker) {
System.out.println(invoker + "在调用模块B的功能");
}
}
public static class ModuleC {
public void execute() {
ModuleA moduleA = new ModuleA();
ModuleB moduleB = new ModuleB();
moduleA.execute("模块C");
moduleB.execute("模块C");
}
public void execute(String invoker) {
System.out.println(invoker + "在调用模块C的功能");
}
}
调用方法
public static void main(String[] args) {
ModuleA moduleA = new ModuleA();
ModuleB moduleB = new ModuleB();
ModuleC moduleC = new ModuleC();
moduleA.execute();
moduleB.execute();
moduleC.execute();
}
可能会遇到的问题
模块之间有非常复杂的互相之间的跟蜘蛛网一样的调用。每个模块都要去care很多其他的模块,互相之间耦合很严重。
后面在修改代码的时候,代码不好改,模块B一旦修改了自己的代码,可能会影响模块A和模块C
1.3.2. 使用设计模式方式
使用中介者模式后,各个系统只要知道一个中介者就可以了,具体跟其他模块的交互都封装在中介者里面。
系统之间不再有任何的耦合,不再有复杂的交互关系,互相之间修改不会对对方产生什么影响。
接口及数据对象
public static class Mediator {
private ModuleA moduleA;
private ModuleB moduleB;
private ModuleC moduleC;
public ModuleA getModuleA() {
return moduleA;
}
public void setModuleA(ModuleA moduleA) {
this.moduleA = moduleA;
}
public ModuleB getModuleB() {
return moduleB;
}
public void setModuleB(ModuleB moduleB) {
this.moduleB = moduleB;
}
public ModuleC getModuleC() {
return moduleC;
}
public void setModuleC(ModuleC moduleC) {
this.moduleC = moduleC;
}
public void moduleAInvoke() {
moduleB.execute("模块A通知中介者");
moduleC.execute("模块A通知中介者");
}
public void moduleBInvoke() {
moduleA.execute("模块B通知中介者");
moduleC.execute("模块B通知中介者");
}
public void moduleCInvoke() {
moduleA.execute("模块C通知中介者");
moduleB.execute("模块C通知中介者");
}
}
public static class ModuleA {
private Mediator mediator;
public ModuleA(Mediator mediator) {
this.mediator = mediator;
this.mediator.setModuleA(this);
}
public void execute() {
mediator.moduleAInvoke();
}
public void execute(String invoker) {
System.out.println(invoker + "在调用模块A的功能");
}
}
public static class ModuleB {
private Mediator mediator;
public ModuleB(Mediator mediator) {
this.mediator = mediator;
this.mediator.setModuleB(this);
}
public void execute() {
mediator.moduleBInvoke();
}
public void execute(String invoker) {
System.out.println(invoker + "在调用模块B的功能");
}
}
public static class ModuleC {
private Mediator mediator;
public ModuleC(Mediator mediator) {
this.mediator = mediator;
this.mediator.setModuleC(this);
}
public void execute() {
mediator.moduleCInvoke();
}
public void execute(String invoker) {
System.out.println(invoker + "在调用模块C的功能");
}
}
调用方法
public static void main(String[] args) {
Mediator mediator = new Mediator();
ModuleA moduleA = new ModuleA(mediator);
ModuleB moduleB = new ModuleB(mediator);
ModuleC moduleC = new ModuleC(mediator);
moduleA.execute();
moduleB.execute();
moduleC.execute();
}