[设计模式] 调停者模式(Mediator Pattern)
什么是调停者模式?
调停者模式是一种旨在降低一系列对象之间耦合关系的设计模式。在一个系统中,对象与对象之间是不可避免发生各种通信,共同合作完成特定的功能。我们把这些对象成为同事对象(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)相关推荐
- 设计模式-中介者模式(Mediator Pattern)
设计模式-中介者模式(Mediator Pattern) 文章目录 设计模式-中介者模式(Mediator Pattern) 一.定义 二.概念解释 三.场景 四.实现 1.类图 2.代码实现 五.总 ...
- 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)
[索引页] [源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:webabcd 介绍 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互 ...
- PHP设计模式之中介者模式(Mediator Pattern)了解下
咱们先来看下中介者模式(Mediator Pattern)的定义,它就是,用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互, ...
- 《Java设计模式》之调停者模式(Mediator)
调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从而使它们能够较松散地耦合.当这些对象中的某些对象之间的相互作用发生改变时,不会马上影响到其它的一些 ...
- 7.7 中介者模式(Mediator Pattern)
一. 定义 在现实生活中,常出现多个对象之间存在复杂的交互关系,这种交互关系常常是"网状结构",要求每个对象都必须知道它需要交互的对象.如:每个人必须记住他所有朋友的电话,若朋友中 ...
- 乐在其中设计模式(C#) - 提供者模式(Provider Pattern)
原文:乐在其中设计模式(C#) - 提供者模式(Provider Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 提供者模式(Provider Pattern) 作者:web ...
- 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)
[索引页] [源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:webabcd 介绍 用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象. ...
- 乐在其中设计模式(C#) - 命令模式(Command Pattern)
原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...
- java中介者模式例子_Java中介者模式(Mediator Pattern)
本篇文章帮大家学习java中介者模式(Mediator Pattern),包含了Java中介者模式(Mediator Pattern)使用方法.操作技巧.实例演示和注意事项,有一定的学习价值,大家可以 ...
- java 访客模式,设计模式 - 访客模式( Visitor Pattern)
设计模式 - 访客模式( Visitor Pattern) 在Visitor模式中,我们使用一个访问者类来更改元素类的执行算法. 通过这种方式,元素的执行算法可以随着访问者的变化而变化. 此模式属于行 ...
最新文章
- linux下使用binfmt_misc设定不同二进制的打开程序
- Eclipse遇到的错误
- 分支结构,循环结构,for循环,九九乘法表
- IIS7开启gZip动态压缩
- 软件工程详细设计说明书_软件工程导论知识点梳理之简答题
- excel能创建html吗,如何通过Excel电子表格使用循环创建单独的HTML发布页面
- Windows C++界面库
- C:\Windows\System32\drivers\etc下的hosts修改方法
- 机械设计与制造专业学习嵌入式单片机开发容易吗?
- WordPress纯代码高仿 无觅相关文章 图文模式功能
- 如何让小孩练得一手好字?这5个小方法,家长不妨试试
- 列联表分析-独立性检验
- 5G无线技术基础自学系列 | 移动通信网络的架构
- 电脑提醒没有权限在此位置保存文件怎么办?
- Vue的双向数据绑定
- 2020牛客暑期多校训练营(第九场) 	The Flee Plan of Groundhog
- 腾讯云轻量服务器与CVM的区别?
- 微信关注公众号获取用户信息
- STM32之vl53l0x读取距离
- 语义分割——Enet模型实现