什么是调停者模式?

调停者模式是一种旨在降低一系列对象之间耦合关系的设计模式。在一个系统中,对象与对象之间是不可避免发生各种通信,共同合作完成特定的功能。我们把这些对象成为同事对象(Collegue)。通过将同事对象之间的交互逻辑提取、封装在调停者(Mediator)对象里,消除了这些对象之间明显的相互引用,让它们只通过一个调停者进行合作,从而降低了对象之间的耦合度,增加对象的可复用性。

为什么要使用调停者模式?

在不使用调停者模式的代码中,同事对象之间的调用关系可能是一个复杂的网状结构,如下图所示
上图所示的系统就是一个过度耦合的系统,这种系统如果要加入一个新的对象,就要考虑新对象与所有已有对象之间的交互作用,使这个系统的扩展变得特别困难。那么我们把每个对象之间的交互集中在一个中间类里,让所有的对象只跟这一个中间类交互,就把这种网状结构转换成了星状结构

在这种结构的系统中,我们新加一个对象的时候,只需要考虑这个对象怎么跟调停者对象交互即可,大大提高了系统的可扩展性。

我们用一个简易版的斗地主案例,来说明一下在不使用调停者模式下,对象之间交互的复杂性。

我们都知道,斗地主的规则里,如果地主获胜了,自己加分,两个农民扣分。而如果一个农民胜了,那么自己和另一个农民加分,地主扣分。

// 地主类
public class Landlord {private int score; // 现有分数public Landlord() {this.score = 0;}public void win(Farmer[] farmers) {this.score += 20;for(Farmer farmer : farmers) {farmer.lose();}}public void lose() {this.score -= 20;}
}// 农民类
public class Farmer {private int score;public Farmer() {this.score = 0;}public void win(Farmer anotherFarmer, Landlord landlord) {this.score += 10;anotherFarmer.win();landlord.lose();}public void lose() {this.score -= 10;}
}// 游戏类
public class GameBoard {public static void main(String[] args) {Landlord landlord = new Landlord();Farmer farmer1 = new Farmer();Farmer farmer2 = new Farmer();// 地主胜landlord.win(new Farmer[] {farmer1, farmer2});// 农民胜farmer1.win(farmer2, landlord);}
}

上面的例子就可以看出,不管是农民胜了还是地主胜了,都要兼顾三方的分数计算,如果出现了一丝纰漏可能就会导致最后的结果出现错误。那么,我们如果有那么一个调停者,让调停者负责分数的计算,地主和农民只告诉调停者那一局的结果即可。

怎么使用调停者模式?

调停者模式是必须有下面四个角色的:

  • 抽象调停者: 定义了同事类与调停者交互的接口,其中主要方法是一个事件方法。
  • 具体调停者: 实现了抽象调停者定义的事件方法,同时具体调停者知道所有具体的同事类,并且负责协调各同事类之间的交互。
  • 抽象同事类:定义了调停者和同事类的交互接口,同事对象只知道调停者,而不知道其他的同事对象。
  • 具体同事类:具体同事类都是继承自抽象同事类。实现自己的业务,然后当要与其他同事类进行通信的时候,就与持有的调停者进行通信,调停者负责与其他同事类进行交互。

那么我们继续用上面斗地主的例子,来看看如果应用了调停者模式,代码会变成什么样。

// 抽象同事类
public abstract class AbstractPlayer {protected AbstractGameMediator mediator;private int score;public AbstractPlayer(AbstractGameMediator mediator) {score = 0;}public void win() {this.mediator.someoneWin(this);}public void addPoint(int point) {this.score += point;}public void cutPoint(int point) {this.score -= point;}
}// 农民玩家
public class Farmer extends AbstractPlayer {public Farmer(AbstractGameMediator mediator) {super(mediator);this.mediator.registerFarmerPlayer(this);}
}// 地主玩家
public class Landlord extends AbstractPlayer {public Landlord(AbstractGameMediator mediator) {super(mediator);this.mediator.setLandlordPlayer(this);}
}// 抽象调停者
public abstract class AbstractGameMediator {public abstract void someoneWin(AbstractPlayer caller);
}public class GameMediator() extends AbstractGameMediator {private Landlord landlord;private List<Farmer> farmers = new ArrayList<>();public void setLandlordPlayer(Landlord landlord) {this.landlord = landlord;}public void registerFarmerPlayer(Farmer farmer) {this.farmers.add(farmer);}@Overridepublic void someoneWin(AbstractPlayer caller) {if (caller instanceof Landlord) {   // 调用该方法的同事对象是地主玩家landlord.addPoint(20);    // 地主玩家加20分for (Farmer farmer : farmers) {farmer.cutPoint(10);  // 农民玩家减10分}} else if (caller instanceof Farmer) {  // 调用该方法的同事对象是农民玩家landlord.cutPoint(20);    // 地主玩家减20分for (Farmer farmer : farmers) {farmer.addPoint(10);  //每个农民加10分}}}
}public class GameBoard {public static void main(String[] args) {GameMediator mediator = new GameMeDiator();Landlord landlord = new Landlord(mediator);Farmer farmer1 = new Farmer(mediator);Farmer farmer2 = new Farmer(mediator);// 地主胜landlord.win();// 农民胜farmer1.win();}
}

上面的代码,我们把控制其他同事对象的分数的代码抽取出来,单独的放在了调停者对象(GameMediator)中,这样,各个同事对象并不知道其他同事对象的存在,也不用费劲心思的考虑有没有算对其他同事对象的分数了。同时,也让对象之间的关系更加容易理解。

调停者模式的缺点

  • 过度集中化: 因为我们把所有交互逻辑都放在的调停者中,那么就会导致这个调停者对象会比任何一个具体同事类都要复杂。这样就会导致调试的不便,并且难于管理和维护。

[设计模式] 调停者模式(Mediator Pattern)相关推荐

  1. 设计模式-中介者模式(Mediator Pattern)

    设计模式-中介者模式(Mediator Pattern) 文章目录 设计模式-中介者模式(Mediator Pattern) 一.定义 二.概念解释 三.场景 四.实现 1.类图 2.代码实现 五.总 ...

  2. 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)

    [索引页] [源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:webabcd 介绍 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互 ...

  3. PHP设计模式之中介者模式(Mediator Pattern)了解下

    咱们先来看下中介者模式(Mediator Pattern)的定义,它就是,用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互, ...

  4. 《Java设计模式》之调停者模式(Mediator)

    调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从而使它们能够较松散地耦合.当这些对象中的某些对象之间的相互作用发生改变时,不会马上影响到其它的一些 ...

  5. 7.7 中介者模式(Mediator Pattern)

    一. 定义 在现实生活中,常出现多个对象之间存在复杂的交互关系,这种交互关系常常是"网状结构",要求每个对象都必须知道它需要交互的对象.如:每个人必须记住他所有朋友的电话,若朋友中 ...

  6. 乐在其中设计模式(C#) - 提供者模式(Provider Pattern)

    原文:乐在其中设计模式(C#) - 提供者模式(Provider Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 提供者模式(Provider Pattern) 作者:web ...

  7. 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)

    [索引页] [源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:webabcd 介绍 用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象. ...

  8. 乐在其中设计模式(C#) - 命令模式(Command Pattern)

    原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...

  9. java中介者模式例子_Java中介者模式(Mediator Pattern)

    本篇文章帮大家学习java中介者模式(Mediator Pattern),包含了Java中介者模式(Mediator Pattern)使用方法.操作技巧.实例演示和注意事项,有一定的学习价值,大家可以 ...

  10. java 访客模式,设计模式 - 访客模式( Visitor Pattern)

    设计模式 - 访客模式( Visitor Pattern) 在Visitor模式中,我们使用一个访问者类来更改元素类的执行算法. 通过这种方式,元素的执行算法可以随着访问者的变化而变化. 此模式属于行 ...

最新文章

  1. linux下使用binfmt_misc设定不同二进制的打开程序
  2. Eclipse遇到的错误
  3. 分支结构,循环结构,for循环,九九乘法表
  4. IIS7开启gZip动态压缩
  5. 软件工程详细设计说明书_软件工程导论知识点梳理之简答题
  6. excel能创建html吗,如何通过Excel电子表格使用循环创建单独的HTML发布页面
  7. Windows C++界面库
  8. C:\Windows\System32\drivers\etc下的hosts修改方法
  9. 机械设计与制造专业学习嵌入式单片机开发容易吗?
  10. WordPress纯代码高仿 无觅相关文章 图文模式功能
  11. 如何让小孩练得一手好字?这5个小方法,家长不妨试试
  12. 列联表分析-独立性检验
  13. 5G无线技术基础自学系列 | 移动通信网络的架构
  14. 电脑提醒没有权限在此位置保存文件怎么办?
  15. Vue的双向数据绑定
  16. 2020牛客暑期多校训练营(第九场) The Flee Plan of Groundhog
  17. 腾讯云轻量服务器与CVM的区别?
  18. 微信关注公众号获取用户信息
  19. STM32之vl53l0x读取距离
  20. 语义分割——Enet模型实现

热门文章

  1. 当析构函数遇到多线程 ── C++ 中线程安全的对象回调
  2. SyncToy使用介绍
  3. 《淘宝网开店 拍摄 修图 设计 装修 实战150招》一一
  4. 智能化汽车3D ToF摄像头
  5. CGMB 奔驰钥匙积分 以及 奔驰怪兽详细功能介绍 奔驰调表 奔驰擦空变数箱电脑等等
  6. 微信小程序——章节自测七
  7. 个人晋升演讲ppt_如何写好公司级别晋升 PPT?
  8. Windbg调试命令详解(2)
  9. 2022年财务顾问FA行业研究报告
  10. 计算机学院运动会解说词,学校运动会解说词30篇