场景 (1)三个模块 (2)模块1调用模块2和模块3;模块2要调用模块1和模块3;模块3要调用模块1和模块2

1.常规

  1. package com.example.demo.pattern.mediator;
  2. /**
  3. * @author chenchao
  4. * @date 2021/11/9
  5. */
  6. public class WithoutMediatorPatternDemo {
  7. public static void main(String[] args) {
  8. ModuleA moduleA = new ModuleA();
  9. ModuleB moduleB = new ModuleB();
  10. ModuleC moduleC = new ModuleC();
  11. moduleA.execute();
  12. moduleB.execute();
  13. moduleC.execute();
  14. // 模块之间有非常复杂的互相之间的跟蜘蛛网一样的调用
  15. // 问题,每个模块都要去care很多其他的模块,互相之间耦合很严重
  16. // 后面在修改代码的时候,代码不好改,模块B一旦修改了自己的代码,可能会影响模块A和模块C
  17. }
  18. public static class ModuleA {
  19. public void execute() {
  20. ModuleB moduleB = new ModuleB();
  21. ModuleC moduleC = new ModuleC();
  22. moduleB.execute("模块A");
  23. moduleC.execute("模块A");
  24. }
  25. public void execute(String invoker) {
  26. System.out.println(invoker + "在调用模块A的功能");
  27. }
  28. }
  29. public static class ModuleB {
  30. public void execute() {
  31. ModuleA moduleA = new ModuleA();
  32. ModuleC moduleC = new ModuleC();
  33. moduleA.execute("模块B");
  34. moduleC.execute("模块B");
  35. }
  36. public void execute(String invoker) {
  37. System.out.println(invoker + "在调用模块B的功能");
  38. }
  39. }
  40. public static class ModuleC {
  41. public void execute() {
  42. ModuleA moduleA = new ModuleA();
  43. ModuleB moduleB = new ModuleB();
  44. moduleA.execute("模块C");
  45. moduleB.execute("模块C");
  46. }
  47. public void execute(String invoker) {
  48. System.out.println(invoker + "在调用模块C的功能");
  49. }
  50. }
  51. }

2.中介者模式

  1. package com.example.demo.pattern.mediator;
  2. /**
  3. * @author chenchao
  4. * @date 2021/11/9
  5. */
  6. public class MediatorPatternDemo {
  7. public static void main(String[] args) {
  8. Mediator mediator = new Mediator();
  9. ModuleA moduleA = new ModuleA(mediator);
  10. ModuleB moduleB = new ModuleB(mediator);
  11. ModuleC moduleC = new ModuleC(mediator);
  12. moduleA.execute();
  13. moduleB.execute();
  14. moduleC.execute();
  15. // 好处在哪儿
  16. // moduleA,只要知道一个中介者就可以了,具体跟其他模块的交互都封装在中介者里面了
  17. // moduleB,同上
  18. // moduleC,同上
  19. // moduleA、B、C之间不再有任何的耦合,不再有复杂的交互关系,互相之间修改不会对对方产生什么影响
  20. }
  21. public static class Mediator {
  22. private ModuleA moduleA;
  23. private ModuleB moduleB;
  24. private ModuleC moduleC;
  25. public ModuleA getModuleA() {
  26. return moduleA;
  27. }
  28. public void setModuleA(ModuleA moduleA) {
  29. this.moduleA = moduleA;
  30. }
  31. public ModuleB getModuleB() {
  32. return moduleB;
  33. }
  34. public void setModuleB(ModuleB moduleB) {
  35. this.moduleB = moduleB;
  36. }
  37. public ModuleC getModuleC() {
  38. return moduleC;
  39. }
  40. public void setModuleC(ModuleC moduleC) {
  41. this.moduleC = moduleC;
  42. }
  43. public void moduleAInvoke() {
  44. moduleB.execute("模块A通知中介者");
  45. moduleC.execute("模块A通知中介者");
  46. }
  47. public void moduleBInvoke() {
  48. moduleA.execute("模块B通知中介者");
  49. moduleC.execute("模块B通知中介者");
  50. }
  51. public void moduleCInvoke() {
  52. moduleA.execute("模块C通知中介者");
  53. moduleB.execute("模块C通知中介者");
  54. }
  55. }
  56. public static class ModuleA {
  57. private Mediator mediator;
  58. public ModuleA(Mediator mediator) {
  59. this.mediator = mediator;
  60. this.mediator.setModuleA(this);
  61. }
  62. public void execute() {
  63. mediator.moduleAInvoke();
  64. }
  65. public void execute(String invoker) {
  66. System.out.println(invoker + "在调用模块A的功能");
  67. }
  68. }
  69. public static class ModuleB {
  70. private Mediator mediator;
  71. public ModuleB(Mediator mediator) {
  72. this.mediator = mediator;
  73. this.mediator.setModuleB(this);
  74. }
  75. public void execute() {
  76. mediator.moduleBInvoke();
  77. }
  78. public void execute(String invoker) {
  79. System.out.println(invoker + "在调用模块B的功能");
  80. }
  81. }
  82. public static class ModuleC {
  83. private Mediator mediator;
  84. public ModuleC(Mediator mediator) {
  85. this.mediator = mediator;
  86. this.mediator.setModuleC(this);
  87. }
  88. public void execute() {
  89. mediator.moduleCInvoke();
  90. }
  91. public void execute(String invoker) {
  92. System.out.println(invoker + "在调用模块C的功能");
  93. }
  94. }
  95. }

3.说明

这个模式,担心的就是系统中各个子系统之前互相之间调用,乱成一团。所以就将系统之间互相调用的逻辑给放到一个所谓的中介者里面去。每个系统如果要通知别的系统干个什么事儿,直接就是调用中介者,中介者负责去调用别的系统。

我们来思考一下这个本质,其实说白了,这个模式就是要让各个系统之间彻底解耦,不要互相强耦合在一起,互相调用过多,调用关系过于混乱。互相调用的时候通过一个中间的组件来解耦。

在实际的企业开发中,不是这么玩儿的,很少有见到说封装一个所谓的中介者,去让各个模块之间解耦,思考这个模式的本质,让各个模块之间解耦合

最最常见的一个方式,就是系统与系统之间,不是走直接的接口调用,而是基于MQ来解耦。录入过模块A要调用模块B和模块C,模块A发送一条消息到MQ里面去,模块B和模块C去消费这条消息,读到消息之后,知道模块A要调用自己,所以就执行对应的逻辑即可。常见于系统与系统之间的调用,可以基于MQ消息,异步执行的方式来调用,不需要同步调用和执行。

大家想一下,这不就是典型的各个子系统用MQ来解耦么,有些操作,互相直接不是直接调用,消息发送到MQ,通过MQ来解耦。我们在电商系统里也完全有这种场景,到后面我们设计系统的时候给大家分析。我们可以封装一个基于内存队列的异步解耦中介者组件,然后让系统间有些可以异步的操作通过中介者来执行,降低互相调用的复杂度。

模块A将消息发送到一个内存队列中去,其他的模块去内存队列中消费自己感兴趣的消息,来执行对应的操作,用队列替代了中介者,让各个模块之间解耦合,rabbitmq去做