轻松掌握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 相关文章推荐
window.name代替cookie的实现代码
Nov 28 Javascript
jQuery中调用WebService方法小结
Mar 28 Javascript
基于mootools 1.3框架下的图片滑动效果代码
Apr 22 Javascript
uploadify 3.0 详细使用说明
Jun 18 Javascript
图标线性回归斜着移动到指定的位置
Aug 16 Javascript
JavaScript设计模式之抽象工厂模式介绍
Dec 28 Javascript
javascript实现确定和取消提示框效果
Jul 10 Javascript
JS中script标签defer和async属性的区别详解
Aug 12 Javascript
react.js 父子组件数据绑定实时通讯的示例代码
Sep 25 Javascript
Layer弹出层动态获取数据的方法
Aug 20 Javascript
layui问题之自动滚动二级iframe页面到指定位置的方法
Sep 18 Javascript
基于layui的下拉列表的数据回显方法
Sep 24 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 mysql_query执行超时(Fatal error: Maximum execution time …)
2013/07/03 PHP
基于PHP实现简单的随机抽奖小程序
2016/01/05 PHP
浅谈PHP检查数组中是否存在某个值 in_array 函数
2016/06/13 PHP
经典的解除许多网站无法复制文字的绝招
2006/12/31 Javascript
JS event使用方法详解
2008/04/28 Javascript
FLASH 广告之外的链接
2008/12/16 Javascript
JavaScript 继承的实现
2009/07/09 Javascript
javascript自执行函数之伪命名空间封装法
2010/12/25 Javascript
jQuery focus和blur事件的应用详解
2014/01/26 Javascript
jquery搜索框效果实现方法
2015/01/16 Javascript
jquery插件jSignature实现手动签名
2015/05/04 Javascript
angularjs表格分页功能详解
2016/01/21 Javascript
javascript实现任务栏消息提示的简单实例
2016/05/31 Javascript
jQuery实现底部浮动窗口效果
2016/09/07 Javascript
jQuery+正则+文本框只能输入数字的实现方法
2016/10/07 Javascript
Bootstrap 设置datetimepicker在屏幕上面弹出设置方法
2017/03/21 Javascript
AngularJS中的拦截器实例详解
2017/04/07 Javascript
vue中slot(插槽)的介绍与使用
2018/11/12 Javascript
ant-design-vue按需加载的坑的解决
2020/05/14 Javascript
[00:38]TI珍贵瞬间系列(二):笑
2020/08/26 DOTA
python命令行参数解析OptionParser类用法实例
2014/10/09 Python
python pyheatmap包绘制热力图
2018/11/09 Python
python http基本验证方法
2018/12/26 Python
Python实现自动访问网页的例子
2020/02/21 Python
postman和python mock测试过程图解
2020/02/22 Python
Python matplotlib画图时图例说明(legend)放到图像外侧详解
2020/05/16 Python
HTML5 Video/Audio播放本地文件示例介绍
2013/11/18 HTML / CSS
美国保健品专家:Life Extension
2018/05/04 全球购物
运动会闭幕式解说词
2014/02/21 职场文书
学习十八大坚定理想信念心得体会
2014/03/11 职场文书
幼儿园保育员岗位职责
2014/04/13 职场文书
森林病虫害防治方案
2014/06/02 职场文书
项目合作意向书模板
2014/07/29 职场文书
2015年元宵节活动总结
2015/02/06 职场文书
党小组意见范文
2015/06/08 职场文书
大学生支教感言
2015/08/01 职场文书