Js中的中介者模式
定义
定义一个中介者对象来封装一系列对象的交互,把一批原来交互关系复杂的对象转换成一组松散耦合的对象,使他们变得易于维护和修改。
详细描述
在我们开发中经常会将对象拆分为更小的颗粒度,可以提高对象的复用性,但是在很多场景下对象与对象之间会存在很多交互和依赖关系它们之间的关系会随着迭代越来越复杂复杂如下图所示:
这时候如果我们在想要去维护它们之间的关系时就需要小心翼翼的捋清楚它们之间所有的影响,会对我我们的开发造成很大的困扰。所以就有了今天看到的中介者模式,它将和所有的对象之间建立通信,对象之间的改变和操作都只需要通知给中介者对象即可。它将其他对象之间的关系全部解耦使原来多对多的复杂关系变为简单的一对多关系。如下图:
在现实生活中也有很多这样的场景如机场的塔台调度系统,所有的飞机只需要和塔台进行通信就可以知道航线是否安全,是否会有其他飞机干扰等,不需要飞机和飞机之间自己确认位置信息。
应用场景:聊天室、表单操作、mvc框架等。
代码实例
下面我们就简单来模拟一个韩梅梅群发消息通知其他人一起打游戏的功能,先不使用中介者模式实现:
// 人员
class People {
constructor(name) {
this.name = name;
this.peoples = [];
}
// 广播
broadcast(text, name) {
console.log(`${name}: ${text}`);
}
// 通知
notice(text) {
this.peoples.forEach((element) => element.broadcast(text, this.name));
}
addPeople(people) {
this.peoples.push(people);
}
}
// 实例三个人
const p1 = new People('韩梅梅');
const p2 = new People('李雷');
const p3 = new People('黄哈哈');
// 分别关联需要交互的对象
p1.addPeople(p2);
p1.addPeople(p3);
p2.addPeople(p1);
p2.addPeople(p3);
p3.addPeople(p1);
p3.addPeople(p2);
// 开始沟通
p1.notice('七点开始集合,上号');
p2.notice('马上就来');
p3.notice('兄弟们我要去约会,去不了');
// 打印
// 韩梅梅: 七点开始集合,上号 *2
// 李雷: 马上就来 *2
// 黄哈哈: 兄弟们我要去约会,去不了 *2
上述代码中,创建了三个人其中韩梅梅要喊其他人一起玩游戏,但是黄哈哈为了给他俩创造空间决定所以找个理由拒绝了。我们可以看到三个实例对象p1、p2、p3之间都会有交互所以他们每个人都要去维护需要通知的人,然后再一一通知到他们要做什么,假如此时还需要喊一个人加入,那么所有人都要将新加入的那个人维护到自己的关联列表中,这样不但不方便,还会使得每个人都需要很大的心智负担。下面我们看下使用中介者模式来实现如下:
// 广播类
class Intermediary {
constructor() {
this.peoples = [];
}
// 广播
broadcast(text, name) {
this.peoples.forEach((element) => {
element.name !== name && element.broadcast(text, name);
});
}
// 添加人员
addPeople(people) {
this.peoples.push(people);
}
}
// 人员
class People {
constructor(name) {
this.name = name;
// this.peoples = null;
}
// 广播
broadcast(text, name) {
console.log(`${name}: ${text}`);
}
// 通知
notice(text) {
intermediary.broadcast(text, this.name);
}
}
const p1 = new People('韩梅梅');
const p2 = new People('李雷');
const p3 = new People('黄哈哈');
const intermediary = new Intermediary();
// 添加人员
intermediary.addPeople(p1);
intermediary.addPeople(p2);
intermediary.addPeople(p3);
p1.notice('七点开始集合,上号');
p2.notice('马上就来');
p3.notice('兄弟们我要去约会,去不了');
// 打印;
// 韩梅梅: 七点开始集合,上号 *2
// 李雷: 马上就来 *2
// 黄哈哈: 兄弟们我要去约会,去不了 *2
上述代码新创建了一个中介者对象,这个对象将维护在每个对象中的人员列表接了过来,也就是说现在韩梅梅在想喊小伙伴去玩游戏不需要记住有哪些伙伴,只需要通知给新创建的对象即可,中介者对象会将通知转发给其他的每一个对象。此时如果想添加一个新的队员其他人也不用去关心添加的是谁怎么维护,中介者对象会全部搞定。
总结
优点
- 可以降低各个业务对象之间的耦合度,易于维护
- 可以更方便的复用对象
- 将多对多的交互关系转换为一对多的关系,降低系统复杂度
- 无需修改其他对象就能增加新的对象 易于扩展
缺点
- 会增加一个新的中介者对象
- 封装了太多的交互细节和对象间的关系,可能会使中介者对象变的过于庞大、复杂
中介者模式可以很好的降低对象之间的耦合关系,但是有些时候对象之间有关联是很正常的行为,所以我们要考虑实际的项目和开发场景来合理的使用,否则本应该带来便利的模式可能会因为过度使用而给我们带来很大的负担。