JavaScript中介者模式详解:解耦对象交互与实战案例

作者:拾光时间:2026-10-30 12:58:23浏览:578

本文深入解析JavaScript中的中介者模式,阐述其通过集中控制对象交互来解除紧耦合的核心原理。结合游戏计分板与手机选购两个完整代码案例,展示如何利用中介者对象协调多个组件,提升代码可维护性并遵循迪米特法则。

中介者模式核心原理

中介者模式旨在消除对象间直接的紧密耦合,该模式也被称为“调停者”。所有交互对象不再直接引用彼此,而是统一通过中介者对象进行通信。当某个对象状态发生变化时,仅需通知中介者,由中介者负责协调后续动作。

以机场指挥塔为例,每架飞机只需与指挥塔建立联系。指挥塔掌握所有飞机的实时状态,并据此统一调度起降时间与航线,避免了飞机间的直接协调。

中介者模式严格遵循迪米特法则(最少知识原则),即一个对象应尽可能少地了解其他对象的内部细节。若对象间耦合度过高,修改其中一个对象往往会引发连锁反应,导致维护困难。在高度耦合的场景下,实现局部修改而不影响其他部分极具挑战性。

当对象间的复杂耦合导致调用逻辑混乱且维护成本随项目迭代呈指数级增长时,引入中介者模式进行代码重构是合理的选择。中介者通过集中管理交互逻辑,有效提升了系统的可维护性。

游戏开发案例实现

案例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设计模式与开发实践》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章