轻松掌握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的冒泡事件的阻止与允许(三种实现方法)
Feb 01 Javascript
IE6下拉框图层问题探讨及解决
Jan 03 Javascript
Jquery给基本控件的取值、赋值示例
May 23 Javascript
jQuery简单实现仿京东商城的左侧菜单效果代码
Sep 09 Javascript
Node.js 应用跑得更快 10 个技巧
Apr 03 Javascript
AngularJS表单基本操作
Jan 09 Javascript
JavaScript Base64 作为文件上传的实例代码解析
Feb 14 Javascript
详解ajax的data参数错误导致页面崩溃
Apr 30 Javascript
angular.js实现列表orderby排序的方法
Oct 02 Javascript
详解原生JS回到顶部
Mar 25 Javascript
ES6 Generator函数的应用实例分析
Jun 26 Javascript
vuex页面刷新导致数据丢失的解决方案
Dec 10 Vue.js
修改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 cron中的批处理
2008/09/16 PHP
有关JSON以及JSON在PHP中的应用
2010/04/09 PHP
PHP动态分页函数,PHP开发分页必备啦
2011/11/07 PHP
一个显示某段时间内每个月的方法 返回由这些月份组成的数组
2012/05/16 PHP
生成随机字符串和验证码的类的PHP实例
2013/12/24 PHP
ThinkPHP连接数据库及主从数据库的设置教程
2014/08/22 PHP
PHP批量修改文件名称的方法分析
2017/02/27 PHP
PHP fopen中文文件名乱码问题解决方案
2020/10/28 PHP
jQuery ajax调用WCF服务实例
2014/07/16 Javascript
IE下通过a实现location.href 获取referer的值
2014/09/04 Javascript
javascript实现依次输入input自动定焦
2014/12/23 Javascript
javascript中sort() 方法使用详解
2015/08/30 Javascript
javascript移动开发中touch触摸事件详解
2016/03/18 Javascript
JS实现n秒后自动跳转的两种方法
2020/11/30 Javascript
微信小程序 Page()函数详解
2016/10/17 Javascript
jQuery动态添加.active 实现导航效果代码思路详解
2017/08/29 jQuery
JQuery元素快速查找与操作
2018/04/22 jQuery
Bootstrap开发中Tab标签页切换图表显示问题的解决方法
2018/07/13 Javascript
vue 中 beforeRouteEnter 死循环的问题
2019/04/23 Javascript
vue 进阶之实现父子组件间的传值
2019/04/26 Javascript
vue中的双向数据绑定原理与常见操作技巧详解
2020/03/16 Javascript
Vue2.0 $set()的正确使用详解
2020/07/28 Javascript
Fiddler如何抓取手机APP数据包
2016/01/22 Python
python读取excel表格生成erlang数据
2017/08/26 Python
使用Python AIML搭建聊天机器人的方法示例
2018/07/09 Python
Django处理Ajax发送的Get请求代码详解
2019/07/29 Python
Python 使用 prettytable 库打印表格美化输出功能
2019/12/26 Python
python实现定时发送邮件到指定邮箱
2020/12/23 Python
加拿大购物频道:The Shopping Channel
2016/07/21 全球购物
Fenty Beauty官网:蕾哈娜创立的美妆品牌
2021/01/07 全球购物
计算机应用专业推荐信
2013/11/13 职场文书
2014社区三八妇女节活动总结
2014/03/01 职场文书
国际贸易实训报告
2014/11/05 职场文书
承诺保证书格式
2015/02/28 职场文书
一文搞懂php的垃圾回收机制
2021/06/18 PHP
关于springboot配置druid数据源不生效问题(踩坑记)
2021/09/25 Java/Android