经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
设计模式-行为型-中介者模式
来源:cnblogs  作者:酷学大叔  时间:2019/10/9 10:32:56  对本文有异议

中介者模式(Mediator):

  在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室、QQ群、短信平台和房产中介。不论是QQ游戏还是QQ群,它们都是充当一个中间平台,QQ用户可以登录这个中间平台与其他QQ用户进行交流,如果没有这些中间平台,我们如果想与朋友进行聊天的话,可能就需要当面才可以了。电话、短信也同样是一个中间平台,有了这个中间平台,每个用户都不要直接依赖与其他用户,只需要依赖这个中间平台就可以了,一切操作都由中间平台去分发。中介者模式,定义了一个中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。

  

中介者模式的角色:

  

  1)抽象中介者(Mediator):定义了同事对象到中介者对象的接口。

  2)具体中介者(ConcreteMediator):实现抽象类的方法,它需要知道具体的同事类并从具体同事类接受消息,向具体同事对象发出命令。

  3)抽象同事类(Colleague):定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。

  4)具体同事类(ConcreteColleague):每个具体同事类只知道自己的行为,而不了解其他同事类的情况,但它们认识中介者对象。

示例:

  以现实生活中打牌为例,若不使用中介者模式。

  1. 1 /// <summary>
  2. 2 /// 抽象牌友类
  3. 3 /// </summary>
  4. 4 public abstract class AbstractCardPartner
  5. 5 {
  6. 6 public int Money { get; set; }
  7. 7
  8. 8 public abstract void ChangeMoney(int money, AbstractCardPartner other);
  9. 9 }
  10. 10
  11. 11 /// <summary>
  12. 12 /// 牌友A
  13. 13 /// </summary>
  14. 14 public class PartnerA : AbstractCardPartner
  15. 15 {
  16. 16 public override void ChangeMoney(int money, AbstractCardPartner other)
  17. 17 {
  18. 18 Money += money;
  19. 19 other.Money -= money;
  20. 20 }
  21. 21 }
  22. 22
  23. 23 /// <summary>
  24. 24 /// 牌友B
  25. 25 /// </summary>
  26. 26 public class PartnerB : AbstractCardPartner
  27. 27 {
  28. 28 public override void ChangeMoney(int money, AbstractCardPartner other)
  29. 29 {
  30. 30 Money += money;
  31. 31 other.Money -= money;
  32. 32 }
  33. 33 }
  34. 34
  35. 35 internal class Program
  36. 36 {
  37. 37 private static void Main(string[] args)
  38. 38 {
  39. 39 AbstractCardPartner A = new PartnerA();
  40. 40 A.Money = 20;
  41. 41 AbstractCardPartner B = new PartnerB();
  42. 42 B.Money = 20;
  43. 43
  44. 44 // A赢了B的钱减少
  45. 45 A.ChangeMoney(5, B);
  46. 46 Console.WriteLine("A 现在的钱是:{0}", A.Money); // 应该是25
  47. 47 Console.WriteLine("B 现在的钱是:{0}", B.Money); // 应该是15
  48. 48
  49. 49 // B赢了A的钱减少
  50. 50 B.ChangeMoney(10, A);
  51. 51 Console.WriteLine("A 现在的钱是:{0}", A.Money); // 应该是15
  52. 52 Console.WriteLine("B 现在的钱是:{0}", B.Money); // 应该是25
  53. 53 }
  54. 54 }

  这样的实现确实解决了上面场景中的问题,并且使用了抽象类使具体牌友A和牌友B都依赖于抽象类,从而降低了同事类之间的耦合度。但是如果其中牌友A发生变化时,此时就会影响到牌友B的状态,如果涉及的对象变多的话,这时候某一个牌友的变化将会影响到其他所有相关联的牌友状态。例如牌友A算错了钱,这时候牌友A和牌友B的钱数都不正确了,如果是多个人打牌的话,影响的对象就会更多。这时候就会思考——能不能把算钱的任务交给程序或者算数好的人去计算呢,这时候就有了我们QQ游戏中的欢乐斗地主等牌类游戏了。

  1. 1 /// <summary>
  2. 2 /// 抽象牌友类
  3. 3 /// </summary>
  4. 4 public abstract class AbstractCardPartner
  5. 5 {
  6. 6 protected AbstractMediator mediator;
  7. 7
  8. 8 public int Money { get; set; }
  9. 9
  10. 10 public abstract void Change(int money, AbstractMediator mediator);
  11. 11 }
  12. 12
  13. 13 /// <summary>
  14. 14 /// 牌友A
  15. 15 /// </summary>
  16. 16 public class PartnerA : AbstractCardPartner
  17. 17 {
  18. 18 public PartnerA(int money)
  19. 19 {
  20. 20 Money = money;
  21. 21 }
  22. 22
  23. 23 public override void Change(int money, AbstractMediator mediator)
  24. 24 {
  25. 25 Console.WriteLine($"{nameof(PartnerA)}赢了");
  26. 26 mediator.Change(money, this);
  27. 27 }
  28. 28 }
  29. 29
  30. 30 /// <summary>
  31. 31 /// 牌友B
  32. 32 /// </summary>
  33. 33 public class PartnerB : AbstractCardPartner
  34. 34 {
  35. 35 public PartnerB(int money)
  36. 36 {
  37. 37 Money = money;
  38. 38 }
  39. 39
  40. 40 public override void Change(int money, AbstractMediator mediator)
  41. 41 {
  42. 42 Console.WriteLine($"{nameof(PartnerB)}赢了");
  43. 43 mediator.Change(money, this);
  44. 44 }
  45. 45 }
  46. 46
  47. 47 /// <summary>
  48. 48 /// 牌友B
  49. 49 /// </summary>
  50. 50 public class PartnerC : AbstractCardPartner
  51. 51 {
  52. 52 public PartnerC(int money)
  53. 53 {
  54. 54 Money = money;
  55. 55 }
  56. 56
  57. 57 public override void Change(int money, AbstractMediator mediator)
  58. 58 {
  59. 59 Console.WriteLine($"{nameof(PartnerC)}赢了");
  60. 60 mediator.Change(money, this);
  61. 61 }
  62. 62 }
  63. 63
  64. 64 /// <summary>
  65. 65 /// 抽象中介者类
  66. 66 /// </summary>
  67. 67 public abstract class AbstractMediator
  68. 68 {
  69. 69 public abstract void Register(AbstractCardPartner cardPartner);
  70. 70
  71. 71 // cardPartner赢钱
  72. 72 public abstract void Change(int money, AbstractCardPartner cardPartner);
  73. 73 }
  74. 74
  75. 75 public class Mediator : AbstractMediator
  76. 76 {
  77. 77 private List<AbstractCardPartner> list = new List<AbstractCardPartner>();
  78. 78
  79. 79 public override void Register(AbstractCardPartner cardPartner)
  80. 80 {
  81. 81 list.Add(cardPartner);
  82. 82 }
  83. 83
  84. 84 public override void Change(int money, AbstractCardPartner cardPartner)
  85. 85 {
  86. 86 foreach (var item in list)
  87. 87 {
  88. 88 if (item != cardPartner)
  89. 89 {
  90. 90 cardPartner.Money += money;
  91. 91 item.Money -= money;
  92. 92 }
  93. 93 }
  94. 94 }
  95. 95 }
  96. 96
  97. 97 internal class Program
  98. 98 {
  99. 99 private static void Main(string[] args)
  100. 100 {
  101. 101 AbstractMediator mediator = new Mediator();
  102. 102 AbstractCardPartner A = new PartnerA(20);
  103. 103 AbstractCardPartner B = new PartnerB(20);
  104. 104 AbstractCardPartner C = new PartnerC(20);
  105. 105
  106. 106 mediator.Register(A);
  107. 107 mediator.Register(B);
  108. 108 mediator.Register(C);
  109. 109
  110. 110 // A赢了
  111. 111 A.Change(5, mediator);
  112. 112 Console.WriteLine("A 现在的钱是:{0}", A.Money); // 应该是30
  113. 113 Console.WriteLine("B 现在的钱是:{0}", B.Money); // 应该是15
  114. 114 Console.WriteLine("C 现在的钱是:{0}", C.Money); // 应该是15
  115. 115 }
  116. 116 }

  在上面的实现代码中,抽象中介者类保存了两个抽象牌友类,如果新添加一个牌友类似时,此时就不得不去更改这个抽象中介者类。可以结合观察者模式来解决这个问题,即抽象中介者对象保存抽象牌友的类别,然后添加Register和UnRegister方法来对该列表进行管理,然后在具体中介者类中修改AWin和BWin方法,遍历列表,改变自己和其他牌友的钱数。这样的设计还是存在一个问题——即增加一个新牌友时,此时虽然解决了抽象中介者类不需要修改的问题,但此时还是不得不去修改具体中介者类,即添加CWin方法,我们可以采用状态模式来解决这个问题。

  在写中介者模式的时候,我发现我将其写成了观察者模式,后来仔细研究发现两者还是有区别的:

    中介者模式主要是起到一个协调的作用,它知道所有的同事类且同事类含有中介者对象,即我有事通知你,你帮我协调一下。

    而观察者模式侧重在当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。

中介者模式的优缺点:

  优点:

    1)简化了对象之间的关系,将系统的各个对象之间的相互关系进行封装,将各个同事类解耦,使得系统变为松耦合。

    2)提供系统的灵活性,使得各个同事对象独立而易于复用。

  缺点:

    1)中介者模式中,中介者角色承担了较多的责任,所以一旦这个中介者对象出现了问题,整个系统将会受到重大的影响。

    2)新增加一个同事类时,不得不去修改抽象中介者类和具体中介者类,此时可以使用观察者模式和状态模式来解决这个问题。

中介者使用的场景:

  1)一组定义良好的对象,现在要进行复杂的相互通信。

  2)想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

参考:https://www.runoob.com/design-pattern/mediator-pattern.html

原文链接:http://www.cnblogs.com/az4215/p/11639279.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号