轻松掌握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 相关文章推荐
使用jquery读取html5 localstorage的值的方法
Jan 04 Javascript
js实现右下角可关闭最小化div(可用于展示推荐内容)
Jun 24 Javascript
js中的时间转换—毫秒转换成日期时间的示例代码
Jan 26 Javascript
详细分析使用AngularJS编程中提交表单的方式
Jun 19 Javascript
javascript实现checkbox复选框实例代码
Jan 10 Javascript
JavaScript如何实现跨域请求
Aug 05 Javascript
JavaScript获取服务器时间的方法详解
Dec 11 Javascript
浅谈ES6 模板字符串的具体使用方法
Nov 07 Javascript
微信小程序实现折叠与展开文章功能
Jun 12 Javascript
JS立即执行的匿名函数用法分析
Nov 04 Javascript
js+canvas实现纸牌游戏
Mar 16 Javascript
vue中使用v-for时为什么不能用index作为key
Apr 04 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
深入了解php4(1)--回到未来
2006/10/09 PHP
php实现的获取网站备案信息查询代码(360)
2013/09/23 PHP
PHP实现验证码校验功能
2017/11/16 PHP
PHP7 foreach() 函数修改
2021/03/09 PHP
js技巧--转义符&quot;\&quot;的妙用
2007/01/09 Javascript
项目实践之javascript技巧
2007/12/06 Javascript
js 文件引入实现代码
2010/04/23 Javascript
js常用排序实现代码
2010/12/28 Javascript
js函数调用的方式
2014/05/06 Javascript
jQuery中scrollLeft()方法用法实例
2015/01/16 Javascript
IE浏览器下PNG相关功能
2015/07/05 Javascript
JavaScript中对DOM节点的访问、创建、修改、删除
2015/11/16 Javascript
js获取鼠标点击的对象,点击另一个按钮删除该对象的实现代码
2016/05/13 Javascript
jQuery实现摸拟alert提示框
2016/05/22 Javascript
微信小程序 底部导航栏目开发资料
2016/12/05 Javascript
详解nodejs 文本操作模块-fs模块(一)
2016/12/22 NodeJs
基于JS实现仿京东搜索栏随滑动透明度渐变效果
2017/07/10 Javascript
AngularJS实现controller控制器间共享数据的方法示例
2017/10/30 Javascript
jQuery表单元素过滤选择器用法实例分析
2019/02/20 jQuery
原生js实现的金山打字小游戏(实例代码详解)
2020/03/16 Javascript
微信小程序canvas动态时钟
2020/10/22 Javascript
python高并发异步服务器核心库forkcore使用方法
2013/11/26 Python
跟老齐学Python之有容乃大的list(1)
2014/09/14 Python
用Python脚本来删除指定容量以上的文件的教程
2015/05/04 Python
Python内置函数reversed()用法分析
2018/03/20 Python
Python应用库大全总结
2018/05/30 Python
python计算日期之间的放假日期
2018/06/05 Python
基于Python pip用国内镜像下载的方法
2018/06/12 Python
使用python获取(宜宾市地震信息)地震信息
2019/06/20 Python
GetYourGuide台湾:预订旅游活动、景点和旅游项目
2019/06/10 全球购物
神路信息Java面试题目
2013/03/31 面试题
早会开场白台词大全
2015/06/01 职场文书
力克胡哲观后感
2015/06/10 职场文书
西游降魔篇观后感
2015/06/15 职场文书
教师廉政准则心得体会
2016/01/20 职场文书
CSS3鼠标悬浮过渡缩放效果
2021/04/17 HTML / CSS