轻松掌握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 相关文章推荐
SWFObject Flash js调用类
Jul 08 Javascript
JS 非图片动态loading效果实现代码
Apr 09 Javascript
javascript控制在光标位置插入文字适合表情的插入
Jun 09 Javascript
JavaScript实现级联菜单的方法
Jun 29 Javascript
在React框架中实现一些AngularJS中ng指令的例子
Mar 06 Javascript
canvas绘制万花筒效果(代码分享)
Jan 20 Javascript
vue todo-list组件发布到npm上的方法
Apr 04 Javascript
Vue 通过自定义指令回顾v-内置指令(小结)
Sep 03 Javascript
webpack3升级到webpack4遇到问题总结
Sep 30 Javascript
vue项目配置同一局域网可使用ip访问的操作
Oct 23 Javascript
Vue 3自定义指令开发的相关总结
Jan 29 Vue.js
canvas 中如何实现物体的框选
Aug 05 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 增加了对 .ZIP 文件的读取功能
2006/10/09 PHP
PHP MYSQL乱码问题,使用SET NAMES utf8校正
2009/11/30 PHP
php stream_get_meta_data返回值
2013/09/29 PHP
PHP基于简单递归函数求一个数阶乘的方法示例
2017/04/26 PHP
window.name代替cookie的实现代码
2010/11/28 Javascript
5个javascript的数字格式化函数分享
2011/12/07 Javascript
JS动态创建Table,Tr,Td并赋值的具体实现
2013/07/05 Javascript
Jquery动态进行图片缩略的原理及实现
2013/08/13 Javascript
原生javascript实现图片弹窗交互效果
2015/01/12 Javascript
js实现文本框只允许输入数字并限制数字大小的方法
2015/08/19 Javascript
Bootstrap实现水平排列的表单
2016/07/04 Javascript
最常见的左侧分类菜单栏jQuery实现代码
2016/11/28 Javascript
详解Vue路由钩子及应用场景(小结)
2017/11/07 Javascript
详解vue+vuex+koa2开发环境搭建及示例开发
2018/01/22 Javascript
Vue项目全局配置页面缓存之按需读取缓存的实现详解
2018/08/01 Javascript
详解如何在Vue里建立长按指令
2018/08/20 Javascript
vue模块移动组件的实现示例
2020/05/20 Javascript
Vue 的 v-model用法实例
2020/11/23 Vue.js
Vue实现摇一摇功能(兼容ios13.3以上)
2021/01/26 Vue.js
解决Scrapy安装错误:Microsoft Visual C++ 14.0 is required...
2017/10/01 Python
python+opencv实现动态物体追踪
2018/01/09 Python
python 求某条线上特定x值或y值的点坐标方法
2019/07/09 Python
python自动分箱,计算woe,iv的实例代码
2019/11/22 Python
Python格式化输出--%s,%d,%f的代码解析
2020/04/29 Python
CSS3模块的目前的状况分析
2010/02/24 HTML / CSS
Marriott国际:万豪国际酒店查询预订
2017/09/25 全球购物
Kate Spade美国官网:纽约新兴时尚品牌,以包包闻名于世
2017/11/09 全球购物
西班牙自行车和跑步商店:Alltricks
2018/07/07 全球购物
函授大专自我鉴定
2013/11/01 职场文书
学校七一活动方案
2014/01/19 职场文书
金融事务专业毕业生求职信
2014/02/23 职场文书
岗位标兵事迹材料
2014/05/17 职场文书
热门专业求职信
2014/05/24 职场文书
加薪通知
2015/04/25 职场文书
活动宣传稿范文
2015/07/23 职场文书
一篇文章学会Vue中间件管道
2021/06/20 Vue.js