轻松掌握JavaScript中介者模式


Posted in Javascript onAugust 26, 2016

中介者模式的作用就是解除对象与对象之间的紧耦合关系,它也称‘调停者'。所有的对象都通过中介者对象来通信,而不是相互引用,所以当一个对象发生改变时,只需要通知中介者即可。 

如:机场的指挥塔,每架飞机都只需要和指挥塔通信即可,指挥塔知道每架飞机的飞行状况,可以安排所有起降时间,调整航线等 

中介者模式符合迪米特法则,即最少知识原则,指一个对象应该尽可能少地了解另外的对象。如果对象之间的耦合性太高,则改变一个对象,会牵动很多对象,难于维护。当对象耦合很紧时,要修改一个对象而不影响其它的对象是很困难的。 

如果对象之间的复杂耦合确实导致调用和维护出现了困难,而且这些耦合度随项目的变化呈指数增长,那我们就可以考虑用中介者模式来重构代码!中介者通过解耦来提升代码的可维护性。 

例子1:游戏 
玩家对象是通过Player()构造函数来创建的,有自己的points和name属性。原型上的play()方法负责给自己加一分然后通知中介者:

function Player(name) {
  this.points = 0;
  this.name = name;
}
Player.prototype.play = function () {
  this.points += 1;
  mediator.played();
};

scoreboard对象(计分板)有一个update()方法,它会在每次玩家玩完后被中介者调用。计分析根本不知道玩家的任何信息,也不保存分数,它只负责显示中介者给过来的分数:

var scoreboard = {
  element: document.getElementById('results'),
  update: function (score) {
    var i, msg = '';
    for (i in score) {
      if (score.hasOwnProperty(i)) {
        msg += '<p><strong>' + i + '<\/strong>: ';
        msg += score[i];
        msg += '<\/p>';
      }
    }
    this.element.innerHTML = msg;
  }
};

现在我们来看一下mediator对象(中介者)。在游戏初始化的时候,在setup()方法中创建游戏者,然后放后players属性以便后续使用。played()方法会被游戏者在每轮玩完后调用,它更新score哈希然表然后将它传给scoreboard用于显示。最后一个方法是keypress(),负责处理键盘事件,决定是哪位玩家玩的,并且通知它:

var mediator = {
  players: {},
  setup: function () {
    var players = this.players;
    players.home = new Player('Home');
    players.guest = new Player('Guest');
  },
  played: function () {
    var players = this.players,
    score = {
      Home: players.home.points,
      Guest: players.guest.points
    };
    scoreboard.update(score);
  },
  keypress: function (e) {
    e = e || window.event; // IE
    if (e.which === 49) { // key "1"
      mediator.players.home.play();
      return;
    }
    if (e.which === 48) { // key "0"
      mediator.players.guest.play();
      return;
    }
  }
};

最后一件事是初始化和结束游戏:

// go!
mediator.setup();
window.onkeypress = mediator.keypress;

// game over in 30 seconds
setTimeout(function () {
  window.onkeypress = null;
  alert('Game over!');
}, 30000);

例子2:卖手机

var goods = {  //库存
  'red|32G':3,
  'red|16G':5,
  'blue|32G':3,
  'blue|16G':6
}
//中介者
var mediator = (function(){
  function id(id){
    return document.getElementById(id);
  }
  var colorSelect = id('colorSelect'),
    memorySelect = id('memorySelect'),
    numberInput = id('numberInput'),
    colorInfo = id('colorInfo'),
    memoryInfo = id('memoryInfo'),
    numberInfo = id('numberInfo'),
    nextBtn = id('nextBtn');
  return{
    changed:function(obj){
      var color = colorSelect.value,
        memory = memorySelect.value,
        number = numberInput.value,
        stock = goods[color+'|'+memory];
      if(obj === colorSelect){
        colorInfo.innerHTML = color;
      }else if(obj === memorySelect){
        memoryInfo.innerHTML = memory;
      }else if(obj === numberInput){
        numberInfo.innerHTML = number;
      }
      if(!color){
        nextBtn.disabled = true;
        nextBtn.innerHTML = '请选择手机颜色';
        return;
      }
      if(!memory){
        nextBtn.disabled = true;
        nextBtn.innerHTML = '请选择内存大小';
        return;
      }
      if(Number.isInteger(number-0) && number > 0){
        nextBtn.disabled = true;
        nextBtn.innerHTML = '请输入正确的购买数量';
        return;
      }
      nextBtn.disabled = false;
      nextBtn.innerHTML = '放入购物车';
    }
  }
})();
//添加事件
colorSelect.onchange = function(){
  mediator.changed(this);
}
memorySelect.onchange = function(){
  mediator.changed(this);
}
numberInput.onchange = function(){
  mediator.changed(this);
}

参考文献: 《JavaScript模式》 《JavaScript设计模式与开发实践》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS面向对象编程 for Cookie
Sep 19 Javascript
javascript运行机制之this详细介绍
Feb 07 Javascript
Javscript删除数组中指定元素并返回新数组
Mar 06 Javascript
JS对象与json字符串格式转换实例
Oct 28 Javascript
JS判断是否360安全浏览器极速内核的方法
Jan 29 Javascript
详解js树形控件—zTree使用总结
Dec 28 Javascript
js校验开始时间和结束时间
May 26 Javascript
基于Vue CSR的微前端实现方案实践
May 27 Javascript
JavaScript冒泡算法原理与实现方法深入理解
Jun 04 Javascript
vue中后端做Excel导出功能返回数据流前端的处理操作
Sep 08 Javascript
vantUI 获得piker选中值的自定义ID操作
Nov 04 Javascript
vue 表单输入框不支持focus及blur事件的解决方案
Nov 17 Vue.js
修改jquery中dialog的title属性方法(推荐)
Aug 26 #Javascript
修改Jquery Dialog 位置的实现方法
Aug 26 #Javascript
在线引用最新jquery文件的实现方法
Aug 26 #Javascript
纯前端JavaScript实现Excel IO案例分享
Aug 26 #Javascript
js时间比较 js计算时间差的简单实现方法
Aug 26 #Javascript
JavaScript toUpperCase()方法使用详解
Aug 26 #Javascript
js遍历map javaScript遍历map的简单实现
Aug 26 #Javascript
You might like
php批量删除数据
2007/01/18 PHP
PHP,ASP.JAVA,JAVA代码格式化工具整理
2010/06/15 PHP
学习php设计模式 php实现策略模式(strategy)
2015/12/07 PHP
php metaphone()函数的定义和用法
2016/05/15 PHP
Laravel搭建后台登录系统步骤详解
2016/07/26 PHP
JavaScript判断一个URL链接是否有效的实现方法
2011/10/08 Javascript
再说AutoComplete自动补全之实现原理
2011/11/05 Javascript
Js 时间函数getYear()的使用问题探讨
2013/04/01 Javascript
jquery 文本上下无缝滚动,鼠标放上去就停止 小例子
2013/06/05 Javascript
JavaScript检查某个function是否是原生代码的方法
2014/08/20 Javascript
node.js中的fs.chmodSync方法使用说明
2014/12/18 Javascript
JS实现超精简响应鼠标显示二级菜单代码
2015/09/12 Javascript
基于JavaScript实现通用tab选项卡(通用性强)
2016/01/07 Javascript
JavaScript数据类型转换的注意事项
2016/07/31 Javascript
web 前端常用组件之Layer弹出层组件
2016/09/22 Javascript
Vue之Watcher源码解析(1)
2017/07/19 Javascript
vue实现通讯录功能
2018/07/14 Javascript
详解nodejs 开发企业微信第三方应用入门教程
2019/03/12 NodeJs
JS实现拼图游戏
2021/01/29 Javascript
js通过循环多张图片实现动画效果
2019/12/19 Javascript
[45:40]Ti4 冒泡赛第二天NEWBEE vs NaVi 1
2014/07/15 DOTA
用Python编写一个简单的俄罗斯方块游戏的教程
2015/04/03 Python
深入Python函数编程的一些特性
2015/04/13 Python
Django自定义插件实现网站登录验证码功能
2017/04/19 Python
numpy实现合并多维矩阵、list的扩展方法
2018/05/08 Python
在pytorch中实现只让指定变量向后传播梯度
2020/02/29 Python
Python GUI编程学习笔记之tkinter控件的介绍及基本使用方法详解
2020/03/30 Python
python实现文件+参数发送request的实例代码
2021/01/05 Python
数据库基础的一些面试题
2012/02/25 面试题
运动会开幕式邀请函
2014/01/22 职场文书
幼儿园教师岗位职责
2014/03/17 职场文书
文体活动总结范文
2014/05/05 职场文书
2014年保洁员工作总结
2014/11/19 职场文书
2016会计专业自荐信范文
2016/01/28 职场文书
golang中的并发和并行
2021/05/08 Golang
Vue2项目中对百度地图的封装使用详解
2022/06/16 Vue.js