轻松掌握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做flash做的事..才完成的一个类.Auntion Action var 0.1
Feb 23 Javascript
jquery聚焦文本框与扩展文本框聚焦方法
Oct 12 Javascript
JavaScript实现节点的删除与序号重建实例
Aug 05 Javascript
BootStrap制作导航条实例代码
May 06 Javascript
轻松掌握JavaScript中介者模式
Aug 26 Javascript
温故知新——JavaScript中的字符串连接问题最全总结(推荐)
Aug 21 Javascript
js 两个日期比较相差多少天的实例
Oct 19 Javascript
Vue.js自定义事件的表单输入组件方法
Mar 08 Javascript
JS实现的简单折叠展开动画效果示例
Apr 28 Javascript
微信小程序自定义对话框弹出和隐藏动画
Jul 19 Javascript
详解微信小程序支付流程与梳理
Jul 16 Javascript
手把手带你入门微信小程序新框架Kbone的使用
Feb 25 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生成带有雪花背景的验证码
2006/10/09 PHP
PHP编码规范-php coding standard
2007/03/16 PHP
PHP多线程类及用法实例
2014/12/03 PHP
javascript forEach通用循环遍历方法
2010/10/11 Javascript
单击按钮显示隐藏子菜单经典案例
2013/01/04 Javascript
jquery给图片添加鼠标经过时的边框效果
2013/11/12 Javascript
jQuery toggleClass应用实例(附效果图)
2014/04/06 Javascript
模拟一个类似百度google的模糊搜索下拉列表
2014/04/15 Javascript
js图片自动轮播代码分享(js图片轮播)
2014/05/06 Javascript
js中json处理总结之JSON.parse
2016/10/14 Javascript
微信小程序 swiper制作tab切换实现附源码
2017/01/21 Javascript
jQuery+pjax简单示例汇总
2017/04/21 jQuery
在Vue中使用Compass的方法
2018/03/02 Javascript
Vue.js 时间转换代码及时间戳转时间字符串
2018/10/16 Javascript
一些你可能不熟悉的JS知识点总结
2019/03/15 Javascript
微信小程序收货地址API兼容低版本解决方法
2019/05/18 Javascript
vue.js中使用微信扫一扫解决invalid signature问题(完美解决)
2020/04/11 Javascript
[47:03]完美世界DOTA2联赛PWL S3 access vs LBZS 第一场 12.20
2020/12/23 DOTA
python中import学习备忘笔记
2017/01/24 Python
详解Python数据可视化编程 - 词云生成并保存(jieba+WordCloud)
2019/03/26 Python
python将字符串list写入excel和txt的实例
2019/07/20 Python
Tensorflow的梯度异步更新示例
2020/01/23 Python
你所在的项目是如何确定版本号的
2015/12/28 面试题
工程部主管岗位职责
2013/11/17 职场文书
大学生职业生涯规划范文——找准自我,定位人生
2014/01/23 职场文书
平安建设实施方案
2014/03/19 职场文书
书香家庭事迹材料
2014/05/09 职场文书
2014年党课学习材料
2014/05/11 职场文书
2014年师德师风学习材料
2014/05/16 职场文书
护士找工作求职信
2014/07/02 职场文书
人事行政专员岗位职责
2014/07/23 职场文书
个人廉政承诺书
2015/04/28 职场文书
道歉的话语大全
2015/05/12 职场文书
亮剑精神观后感
2015/06/05 职场文书
体育部部长竞选稿
2015/11/21 职场文书
深入理解go slice结构
2021/09/15 Golang