再起航,我的学习笔记之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天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...
随机推荐
- Java基础二
1 关键字 定义:被java语言赋予了特殊含义的单词. 特点:关键字中的所有字母都为小写. 用于定义数据类型的关键字 class.interface.byte.short.int.long.float ...
- Codeforces Round #429 (Div. 2) 补题
A. Generous Kefa 题意:n个气球分给k个人,问每个人能否拿到的气球都不一样 解法:显然当某种气球的个数大于K的话,就GG了. #include <bits/stdc++.h> ...
- SkipList跳表基本原理
为什么选择跳表 目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay Tree, Treep等. 想象一下,给你一张草稿纸,一只笔,一个编辑器,你能立即实现一颗红黑树,或者AVL树 出来吗 ...
- 线性代数-矩阵-【4】点乘 C和C++的实现
点击这里可以跳转至 [1]矩阵汇总:http://www.cnblogs.com/HongYi-Liang/p/7287369.html [2]矩阵生成:http://www.cnblogs.com/ ...
- kong介绍-个人分享
kong简介 背景 我们在提供api或微服务时,通常借助openresty nginx进行流量转发或者添加一些规则或功能,但是随着服务数量和引用增多,复杂的网络环境, 使维护变得困难,不容易扩展,一些 ...
- nvm版本控制以及node.js
nvm node.js版本控制工具 下载 nvm 包 地址:https://github.com/coreybutler/nvm-windows/releases 我们选择第一个:nvm-noinst ...
- spring-session 共享
Spring session 共享 一.引入依赖 <dependency> <groupId>redis.clients</groupId> <artifac ...
- selenium 对https网站(加密证书)进行自动化测试
由于公司需要,被测网站有证书加密,由于在selenium启动firefox的时候,它会重新建一个profile作为启动的profile,所以无论你怎么把站点设为可信任站点,在selenium启动的fi ...
- SQL Server 2014 64位版本链接32位Oracle数据库
问题背景: 刚进入公司不久的BI新手,最近接部门的一个交接项目,需要在SQL Server上通过openquery来获取Oracle数据库的数据.各种配置,各种设置折腾了一周之久.在此,将自己的问题解 ...
- 使用 PUTTY 操作 Google Cloud
目的: 使用putty连接Google Cloud 实例. 总说: 首先要用 PuTTYgen生成 private key 和 public key, 之后 登录Google Cloud 将生成的 ...