模式说明

存在许多需要两两交互信息的同类对象,如果互相之间直接交互,将会形成网状结构,每一个对象都需要知道所有其他对象,且若某对象需要修改,那么其他对象可能也要做出修改,造成牵一发动全身的不良后果。针对这种场景,可以设置一个中介者,将对象间的网状两两交互,转变为通过中介者来居中传递信息,能够大大降低同类对象间的耦合,系统也会变得易扩展易维护。例如新增一个需要通信的成员(本设计模式中所谓的同事),只需要创建它并注册到中介者中即可,不影响任何其他成员(同事)。

本示例展示中介者闲鱼平台如何向卖家转发买家的商品需求信息,向买家转发卖家的商品上架信息。当有一个买家发布一条商品需求信息时,所有卖家均能收到。当一个卖家发布一条商品上架信息时,所有买家均能收到。

结构

抽象中介者类
定义管理同事和传递信息的方法。本示例中为注册同事的方法register(User user),转发信息的方法relay(User user, String message)
具体中介者类
继承抽象中介者。持有一个已完成注册的同事的集合List,实现抽象中介者类中的抽象方法registerrelay
抽象同事类
持有一个中介者实例属性,一个名字属性,通过有参构造器初始化名字属性。定义三个抽象方法,设置中介者的方法setMediator,发送消息的方法send,接收消息的方法receive
具体同事类
继承抽象同事类。实现抽象同事类中的三个抽象方法。

代码演示

  1. package com.yukiyama.pattern.behavior;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5. * 中介者模式
  6. */
  7. public class MediatorDemo {
  8. public static void main(String[] args) {
  9. // 声明一个具体中介者实例闲鱼平台
  10. Mediator xianyu = new XianyuMediator();
  11. // 声明卖家1
  12. User seller1 = new Seller("卖家1");
  13. // 声明买家1
  14. User buyer1 = new Buyer("买家1");
  15. // 声明卖家2
  16. User seller2 = new Seller("卖家2");
  17. // 声明买家2
  18. User buyer2 = new Buyer("买家2");
  19. // 将买家和卖家都注册到闲鱼中介者上
  20. xianyu.register(seller1);
  21. xianyu.register(buyer1);
  22. xianyu.register(seller2);
  23. xianyu.register(buyer2);
  24. // 当卖家1发布一条商品上架信息时,所有买家都能收到通过闲鱼中介者转发的该消息
  25. seller1.send("上架了一台小米手机。");
  26. // 当买家1发布一条商品需求信息时,所有卖家都能收到通过闲鱼中介者转发的该消息
  27. buyer1.send("想要一个皮卡丘手办。");
  28. }
  29. }
  30. /**
  31. * 抽象中介者类
  32. * 定义管理同事和传递信息的方法。本示例中为注册同事的方法register(User user),
  33. * 转发信息的方法relay(User user, String message)。
  34. */
  35. abstract class Mediator{
  36. public abstract void register(User user);
  37. public abstract void relay(User user, String message);
  38. }
  39. /**
  40. * 具体中介者类
  41. * 继承抽象中介者。持有一个已完成注册的同事的集合List<User>,实现抽象
  42. * 中介者类中的抽象方法register和relay。relay方法参数为用户User和消息
  43. * message,判断User属于卖家Seller还是买家Buyer,如果是卖家则该消息是
  44. * 一则商品上架消息,通知所有买家该消息。如果是买家则该消息是一则商品需求
  45. * 消息,通知所有卖家该消息。
  46. */
  47. class XianyuMediator extends Mediator{
  48. private List<User> users = new ArrayList<>();
  49. //将user添加到中介者持有的User类集合中,添加时执行User的setMediator方法
  50. @Override
  51. public void register(User user) {
  52. if(!users.contains(user)) {
  53. users.add(user);
  54. user.setMediator(this);
  55. }
  56. }
  57. @Override
  58. public void relay(User user, String message) {
  59. // 打印该用户发出的消息
  60. System.out.println(user.getName()+message);
  61. // 判断用户类型,如果是卖家
  62. if(user instanceof Seller) {
  63. // 所有买家接收该消息
  64. for(User u : users) {
  65. if(u instanceof Buyer) {
  66. u.receive(user.getName()+message);
  67. }
  68. }
  69. }
  70. // 判断用户类型,如果是买家
  71. if(user instanceof Buyer) {
  72. // 所有卖家接收该消息
  73. for(User u : users) {
  74. if(u instanceof Seller) {
  75. u.receive(user.getName()+message);
  76. }
  77. }
  78. }
  79. }
  80. }
  81. /**
  82. * 抽象同事类
  83. * 持有一个中介者实例属性,一个名字属性,通过有参构造器初始化名字属性,
  84. * 并有一个名字属性的getter。
  85. * 定义三个抽象方法,设置中介者的方法setMediator,发送消息的方法send,
  86. * 接收消息的方法receive。
  87. * 本例的同事类为User类。
  88. */
  89. abstract class User{
  90. protected Mediator mediator;
  91. private String name;
  92. public User(String name) {
  93. this.name = name;
  94. }
  95. public String getName() {
  96. return name;
  97. }
  98. public abstract void setMediator(Mediator mediator);
  99. public abstract void send(String message);
  100. public abstract void receive(String message);
  101. }
  102. /**
  103. * 具体同事类
  104. * 继承抽象同事类。实现抽象同事类中的三个抽象方法。setMediator方法传入
  105. * 中介者实例,赋值给该同事类持有的中介者属性。send方法调用中介者的转发
  106. * 方法relay,传入当前同事实例(this)和message。receive方法接收message
  107. * 并打印出来。
  108. * 下例是卖家类。
  109. */
  110. class Seller extends User{
  111. public Seller(String name) {
  112. super(name);
  113. }
  114. @Override
  115. public void setMediator(Mediator mediator) {
  116. this.mediator = mediator;
  117. }
  118. @Override
  119. public void send(String message) {
  120. this.mediator.relay(this, message);
  121. }
  122. @Override
  123. public void receive(String message) {
  124. System.out.println(this.getName() + "收到一条商品需求信息:" + message);
  125. }
  126. }
  127. /**
  128. * 具体同事类
  129. * 下例是买家类。
  130. */
  131. class Buyer extends User{
  132. public Buyer(String name) {
  133. super(name);
  134. }
  135. @Override
  136. public void setMediator(Mediator mediator) {
  137. this.mediator = mediator;
  138. }
  139. @Override
  140. public void send(String message) {
  141. this.mediator.relay(this, message);
  142. }
  143. @Override
  144. public void receive(String message) {
  145. System.out.println(this.getName() + "收到一条商品发布信息:" + message);
  146. }
  147. }