轻松掌握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 相关文章推荐
javascript 混合的构造函数和原型方式,动态原型方式
Dec 07 Javascript
jquery 常用操作方法
Jan 28 Javascript
JavaScript/jQuery 表单美化插件小结
Feb 14 Javascript
JavaScript中Function详解
Feb 27 Javascript
微信JSAPI Ticket接口签名详解
Jun 28 Javascript
JavaScript实现多叉树的递归遍历和非递归遍历算法操作示例
Feb 08 Javascript
Vue组件开发技巧总结
Mar 04 Javascript
Javascript实现购物车功能的详细代码
May 08 Javascript
详解Node.js异步处理的各种写法
Jun 09 Javascript
vue和iview实现Scroll 数据无限滚动功能
Oct 31 Javascript
vue-cli3.X快速创建项目的方法步骤
Nov 14 Javascript
在vue中实现嵌套页面(iframe)
Jul 30 Javascript
修改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 小乘法表实现代码
2009/07/16 PHP
一个PHP数组应该有多大的分析
2009/07/30 PHP
php之curl实现http与https请求的方法
2014/10/21 PHP
PHP采用curl模仿用户登陆新浪微博发微博的方法
2014/11/07 PHP
20个实用的JavaScript技巧分享
2014/11/28 Javascript
JavaScript将字符串转换成字符编码列表的方法
2015/03/19 Javascript
jQuery查看选中对象HTML代码的方法
2016/06/17 Javascript
zTree jQuery 树插件的使用(实例讲解)
2017/09/25 jQuery
[03:00]《DAC最前线》之欧美新秀VS老将
2015/02/01 DOTA
python模块restful使用方法实例
2013/12/10 Python
python使用7z解压软件备份文件脚本分享
2014/02/21 Python
在Python中进行自动化单元测试的教程
2015/04/15 Python
Python中文竖排显示的方法
2015/07/28 Python
详解如何使用Python编写vim插件
2017/11/28 Python
tensorflow 加载部分变量的实例讲解
2018/07/27 Python
python之消除前缀重命名的方法
2018/10/21 Python
Python对象中__del__方法起作用的条件详解
2018/11/01 Python
解决python3 HTMLTestRunner测试报告中文乱码的问题
2018/12/17 Python
如何实现Django Rest framework版本控制
2019/07/25 Python
如何爬取通过ajax加载数据的网站
2019/08/15 Python
Python统计分析模块statistics用法示例
2019/09/06 Python
Django实现网页分页功能
2019/10/31 Python
关于python 跨域处理方式详解
2020/03/28 Python
Python selenium使用autoIT上传附件过程详解
2020/05/26 Python
详解CSS3中常用的样式【基本文本和字体样式】
2020/10/20 HTML / CSS
美国最大的万圣节服装网站:HalloweenCostumes.com
2017/10/12 全球购物
澳洲国民品牌乡村路折扣店:Country Road & Trenery Outlet
2018/04/19 全球购物
创建学习型党组织实施方案
2014/03/29 职场文书
公司投资建议书
2014/05/16 职场文书
节能环保标语
2014/06/12 职场文书
社区服务标语
2014/07/01 职场文书
普通党员四风问题对照检查材料
2014/09/27 职场文书
实习生矿工检讨书
2014/10/13 职场文书
2015年安全教育月活动总结
2015/03/26 职场文书
伊索寓言读书笔记
2015/06/30 职场文书
禁毒心得体会范文
2016/01/15 职场文书