JavaScript中介者模式详解:原理、实现与MVC应用

作者:木棉

时间:2026-10-28

浏览:571

本文深入解析JavaScript中的中介者模式,通过房屋中介类比阐明其封装对象交互、降低耦合的核心价值。文章提供两个完整代码案例:简易聊天室路由与计分板逻辑,并探讨该模式在MVC架构控制层中的实际应用。详细列出中介者模式的适用场景、优缺点及迪米特法则关联,帮助开发者优化复杂系统通信。

文章目录

中介者模式概述

一、总体概要

1、笔者浅谈

我们可以从日常生活中找到一个简单的类比:当人们通过房屋中介租房时,中介人在租客与房东之间建立了一条沟通桥梁。租客无需关心房源的具体归属,房东也不必在意最终承租的是谁。正是由于中介的存在,使得这场交易变得便捷高效。

在软件开发过程中,经常遇到多个类或多个子系统之间相互交互的情况。如果交互过程繁琐,导致每个类都必须知晓其交互对象的具体细节,那么它们之间的耦合度会异常高。这种“牵一发而动全身”的设计往往带来严重的维护后果。

既然问题已经明确,接下来让我们引入本文的主角——中介者模式。

中介者模式概述

聊天室中介者实现

中介者的核心功能在于封装对象之间的交互逻辑。如果某个对象的操作会引发其他相关对象的状态变化,而该对象又不希望直接处理这些复杂关系,就可以委托给中介者来处理这些繁琐的关联。参考以下示例:

代码如下:

var Participant = function(name) {
this.name = name;
this.chatroom = null;
};
Participant.prototype = {
send: function(message, to) {
this.chatroom.send(message, this, to);
    },
receive: function(message, from) {
log.add(from.name + " to " + this.name + ": " + message);
    }
};
var Chatroom = function() {
var participants = {};
return {
register: function(participant) {
participants[participant.name] = participant;
participant.chatroom = this;
        },
send: function(message, from, to) {
if (to) {
to.receive(message, from);
} else {
for (key in participants) {
if (participants[key] !== from) {
participants[key].receive(message, from);
                    }
                }
            }
        }
    };
};
var log = (function() {
var log = "";
return {
add: function(msg) { log += msg + "\n"; },
show: function() { alert(log); log = ""; }
    }
})();
function run() {
var yoko = new Participant("Yoko");
var john = new Participant("John");
var paul = new Participant("Paul");
var ringo = new Participant("Ringo");
var chatroom = new Chatroom();
chatroom.register(yoko);
chatroom.register(john);
chatroom.register(paul);
chatroom.register(ringo);
yoko.send("All you need is love.");
yoko.send("I love you John.");
john.send("Hey, no need to broadcast", yoko);
paul.send("Ha, I heard that!");
ringo.send("Paul, what do you think?", paul);
log.show();
}

在示例代码中,我们定义了四个参与者,他们通过注册加入一个聊天室(即中介)。每个参与者代表一个交互对象。参与者之间发送消息,而聊天室负责处理消息的路由分发。

这里的聊天室对象起到了中介的作用,它协调其他对象进行合理组织,从而有效降低了系统耦合度。

MVC架构中的中介者

二、源码案例参考

我们对MVC三层模型非常熟悉,包括实体模型(Model)、视图表现层(View)以及控制层(Control/Mediator)。

控制层正是位于表现层与模型层之间的中介者。从宏观角度来看,MVC架构也可以被视为中介者模式在框架设计中的一种典型应用。

中介者模式概述

计分板案例代码

三、案例引入

代码如下:

function Player(name) {
this.points = 0;
this.name = name;
}
Player.prototype.play = function () {
this.points += 1;
mediator.played();
};
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;
    }
};
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;
if (e.which === 49) {
mediator.players.home.play();
return;
        }
if (e.which === 48) {
mediator.players.guest.play();
return;
        }
    }
};
mediator.setup();
window.onkeypress = mediator.keypress;
setTimeout(function () {
window.onkeypress = null;
console.log('Game over!');
}, 30000);

模式优缺点与适用场景

四、总结一下

Why Mediator ?

当各个对象之间的交互操作非常多,且每个对象的行为都依赖于其他对象时,修改其中一个对象的行为往往会导致大量其他对象行为的连带修改。

如果使用Mediator模式,可以使各个对象间的耦合变得松散。此时,对象只需关心与Mediator的关系,从而将原本复杂的多对多关系简化为一对多关系。

这种设计能够降低系统的复杂性,并提高系统的可修改性和扩展性。

使用中介者模式的场合

1. 一组定义良好的对象,现在需要进行复杂的通信。

2. 定制一个分布在多个类中的行为,而又不想生成太多的子类。

可以看出,中介对象主要是用来封装行为的。行为的参与者是那些具体对象,但通过中介者,这些对象无需相互知晓(这是迪米特法则的具体实现)。

使用中介者模式的优点:

1. 降低了系统对象之间的耦合性,使得对象易于独立地被复用。

2. 提高系统的灵活性,使得系统易于扩展和维护。

使用中介者模式的缺点:

中介者模式的缺点显而易见,因为这个“中介”承担了较多的责任。因此,一旦这个中介对象出现问题,整个系统就会受到重大影响。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章