再起航,我的学习笔记之JavaScript设计模式23(中介者模式)
中介者模式
概念介绍
中介者模式(Mediator):通过中介者对象封装一系列对象之间的交互,使对象之间不再相互引用降低他们之间的耦合,有时中介者对象也可以改变对象之间的交互。
创建一个中介
中介者模式,从生活的角度上来讲,和我们卖房子的中介很像,比如我有一套房想要出租,而你又想要租房子,那么我们就可以通过中介达成交易,我不考虑租给了岁,租房者也不用考虑租了谁的房子,因为有中介在所以显得很方便。
从代码的角度讲,如果有多个类或多个子系统相互交互,而且交互很繁琐,导致每个类都必须知道他需要交互的类,这样它们的耦合会显得异常厉害,如果这个时候我们需要处理某一个类,那很可能就要陷入无尽的调试中了。
那么这个时候我们就可以用到中介者模式,我们把对象全都交给中介者对象,然后通过中介者对象处理这些复杂的关系。
下面我们模拟一下房东找中介发布消息,租户找中介接收消息吧:
//中介者对象
var Mediator=function(){
//消息对象
var _msg={};
return{
//订阅方法
register:function(type,action){
//如果存在该消息
if(_msg[type]){
//存入回调函数
_msg[type].push(action);
}else{
//不存在我们建立消息容器
_msg[type]=[];
//存入新消息回调函数
_msg[type].push(action);
}
},
//发布方法
send:function(type){
//如果该消息被订阅
if(_msg[type]){
//遍历存储的消息回调函数
for (var i=0;i<_msg[type].length;i++) {
_msg[type][i]&&_msg[type][i]();
}
}
}
}
}();
我们的中介对象创建成功了下面我们来测试一下
Mediator.register('landlord',function(){
console.log('房东发布第一条消息');
});
Mediator.register('landlord',function(){
console.log('房东发布第二条消息');
})
Mediator.register('tenant',function(){
console.log('租户接收第一条消息');
});
Mediator.register('tenant',function(){
console.log('租户接收第二条消息');
})
Mediator.send('landlord');
Mediator.send('tenant');

现在我们的中介者模式成功了。
利用中介者模式实现商品购买
我们现在在编写一个商品购买的页面,在购买流程中,可以选择商品及样式输入购买的数量,同时页面中有两个展示区域,分别向用户展示刚刚选择的商品、种类与数量。还有一个按钮动态显示下一步的操作,我们查询商品对应的库存,如果库存数量少于这次的购买数量,按钮将被禁止且显示库存不足,反之按钮可以点击并且显示放入购买车
页面元素如下:
<select id="shoesBrands">
<option>请选择</option>
<option>Adidas</option>
<option>Nike</option>
</select>
<select id="shoesType">
<option>请选择</option>
<option>运动鞋</option>
<option>球鞋</option>
</select>
<input type="text" id="numberInput" />
<p id="shoesInfo"></p>
<p id="typeInfo"></p>
<p id="numberInfo"></p>
<button id="nextBtn">下一步</button>
接着我们开始写实现方法
//创建一个商品对象记录库存
var goods = {
"Adidas|运动鞋": 23,
"Adidas|球鞋": 35,
"Nike|运动鞋": 0,
"Nike|球鞋": 2
};
//创建中介者对象
var mediator = ( function(){
var shoesBrands = document.getElementById( "shoesBrands" ),
shoesType = document.getElementById( "shoesType" ),
numberInput = document.getElementById( "numberInput" ),
shoesInfo = document.getElementById( "shoesInfo" ),
typeInfo = document.getElementById( "typeInfo" ),
numberInfo = document.getElementById( "numberInfo" ),
nextBtn = document.getElementById( "nextBtn" );
return {
//当选项发生改变时触发下面方法
change: function( obj ){
var shoes = shoesBrands.value, //品牌
type = shoesType.value, //类型
number = numberInput.value, //数量
stock = goods[ shoes + "|" + type ]; //品牌类型下鞋子对应库存数量
if( obj === shoesBrands ){
shoesInfo.innerHTML = shoes;
}else if( obj === shoesType ){
typeInfo.innerHTML = type;
}else if( obj === numberInput ){
numberInfo.innerHTML = number;
}
if( !shoes ){
nextBtn.disabled = true;
shoesInfo.innerHTML = "请选择鞋的品牌";
return;
}
if( !type ){
nextBtn.disabled = true;
typeInfo.innerHTML = "请选择鞋的类型";
return;
}
if( !(Number.isInteger( number - 0 ) && number > 0) ){
//输入购买数量是否为正整数
nextBtn.disabled = true;
numberInfo.innerHTML = "请输入正确的购买数量";
return;
}
if(number>stock){
nextBtn.disabled = true;
nextBtn.innerHTML = "库存不足";
}else{
nextBtn.disabled = false;
nextBtn.innerHTML = "放入购物车";
}
}
}
} )();
我们调用看看
shoesBrands.onchange = function(){
mediator.change( this );
};
shoesType.onchange = function(){
mediator.change( this );
};
numberInput.onchange = function(){
mediator.change( this );
}

总结
同观察者模式一样,中介者模式的主要业务也是通过模块间或者对象间的复杂通信,来解决模块间或对象间的耦合,对于中介者对象的本质是封装多个对象的交互,并且这些交互一般都是在中介者内部实现的。
与外观模式的封装特性相比
中介者模式对多个对象交互地封装,且这些对象一般处于同一层面上,并且封装的交互在中介者内部,而外观模式的封装是为了提供更简单的医用的接口而不会添加其他功能
与观察者模式相比
虽然两种模式都是通过消息传递实现对象间或模块间的解耦。观察者模式中的订阅者是双向的,既可以是消息的发布者,也可以是消息的订阅者。而在中介者模式中,订阅者是单向的,只能是消息的订阅者, 而消息统一由中介者对象发布,所有的订阅者对象间接地被中介者管理
也谢谢大家看到这里:)如果你觉得我的分享还可以请点击推荐,分享给你的朋友让我们一起进步~
好了以上就是本次分享的全部内容,本次示例参考自JavaScript设计模式一书,让我们一点点积累一点点成长,希望对大家有所帮助。
欢迎转载,转载请注明作者,原文出处。
再起航,我的学习笔记之JavaScript设计模式23(中介者模式)的更多相关文章
- 再起航,我的学习笔记之JavaScript设计模式05(简单工程模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...
- 再起航,我的学习笔记之JavaScript设计模式06(工厂方法模式)
上一次已经给大家介绍了简单工厂模式,相信大家对创建型设计模式有了初步的了解,本次我将给大家介绍的是工厂方法模式. 工厂方法模式 工厂方法模式(Factory Method):通过对产品类的抽象使其创建 ...
- 再起航,我的学习笔记之JavaScript设计模式05(简单工厂模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...
- 再起航,我的学习笔记之JavaScript设计模式06(抽象工厂模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...
- 再起航,我的学习笔记之JavaScript设计模式07(抽象工厂模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...
- 再起航,我的学习笔记之JavaScript设计模式30(简单模板模式)
简单模板模式 概念介绍 简单模板模式(Simple template): 通过格式化字符串拼凑出视图避免创建视图时大量节点操作,优化内存开销. 创建模板 在实际的业务中如果我们需要进行前后台交互,或多 ...
- 再起航,我的学习笔记之JavaScript设计模式13(装饰者模式)
装饰者模式 装饰者模式(Decorator): 在不改变原对象的基础上,通过对其进行过包装拓展(添加属性高或者方法)使原有对象可以满足用户的更复杂需求. 如果现在我们有个需求,需要做一个提交表单,当我 ...
- 再起航,我的学习笔记之JavaScript设计模式16(享元模式)
### 享元模式 **享元模式(Flyweight):** 运用共享技术有效地支持大量的细粒度的对象,避免对象间拥有相同内容造成多余的开销. 上回我们在组合模式中创建了文章列表类,这次我们要向不同的文 ...
- 再起航,我的学习笔记之JavaScript设计模式02
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...
随机推荐
- 地图性能测试利器PerfQA Analyzer
PerfQA Analyzer作为一个地图性能测试工具,能针对ArcGIS 技术堆栈的系统进行性能问题的排查,用于系统试运行阶段的压力测试以及在线系统运维.大大减轻了GIS系统管理员的性能调优工作压力 ...
- Windows10系统下,彻底删除卸载MySQL
本文介绍,在Windows10系统下,如何彻底删除卸载MySQL... 1>停止MySQL服务开始->所有应用->Windows管理工具->服务,将MySQL服务停止.2> ...
- Akka(20): Stream:压力缓冲-Batching backpressure and buffering
akka-stream原则上是一种推式(push-model)的数据流.push-model和pull-model的区别在于它们解决问题倾向性:push模式面向高效的数据流下游(fast-downst ...
- C#打印九九乘法表
C#打印九九乘法表... ---------------------------------- using System; using System.Collections.Generic; usin ...
- 大咖云集!IMWebConf 2017 前端大会即将在深圳盛大开幕
2017年火热的夏季,一年一度的IMWebConf强势来袭!9月16日,深圳科兴国际会议中心,我们将全心全意打造一场前端盛宴,恭候各位的光临. 作为一名前端老鸟,笔者有幸也参与了本次的大会的主题分享& ...
- c++中find函数的用法
find函数主要实现的是在容器内查找指定的元素,并且这个元素必须是基本数据类型的.查找成功返回一个指向指定元素的迭代器,即元素在容器中的下标,查找失败返回end迭代器. 头文件 #include &l ...
- [知了堂学习笔记]_纯JS制作《飞机大战》游戏_第1讲(实现思路与游戏界面的实现)
整体效果展示: 一.实现思路 如图,这是我完成该项目的一个逻辑图,也是一个功能模块完成的顺序图. 游戏界面的完成 英雄飞机对象实现,在实现发射子弹方法过程中,又引出了子弹对象并实现.在此时,英雄飞机能 ...
- 边看MHA源码边学Perl语言之一开篇
边看MHA源码边学Perl语言之一开篇 自我简介 先简单介绍一下自己,到目前为此我已经做了7年左右的JAVA和3年左右php开发与管理,做java时主要开发物流行业的相关软件,对台湾快递,国际快递,国 ...
- 第1阶段——u-boot分析之make 100ask24x0_config指令(1)
本文学习目标: 掌握"make 100ask24x0_config"指令在Makefile和mkconfig文件中是怎么实现配置芯片选型 1.执行make 100a ...
- 网络编程:基于C语言的简易代理服务器实现(proxylab)
本文记录了一个基于c socket的简易代理服务器的实现.(CS:APP lab 10 proxy lab) 本代理服务器支持keep-alive连接,将访问记录保存在log文件. Github: h ...