设计模式-javascript实现【中介者模式】
定义:中介者模式的作用就是解除对象与对象之间的紧耦合关系。增加一个中介者对象后,所有的相关对象都
通过中介者对象来通信,而不是互相引用,所以当一个对象发生改变时,只需要通知中介者对象即可。中介者
使各个对象之间耦合松散,而且可以独立地改变它们之间的交互。中介者模式使网状的多对多关系变成了相对
简单的一对多关系。
1. 实现中介者模式
实现中介者对象,一般有以下两种方式
-
利用发布订阅模式。将playerDirector实现为订阅者,各player作为发布者,一旦player的状态发生改变,
便推送消息给playerDirector,playerDirector处理消息后将反馈发送给其他player. -
在playerDirector 中开发一些接受消息的接口,各player可以直接调用该接口来给playerDirector发送
消息,player只需传递一个参数给playerDirector, 这个参数的目的是使playerDirector可以识别发送者。
同样,playerDirector接收到消息之后会将处理结果反馈给其他player。
第二种实现方式:
class PlayerDirector {
constructor(){
this.players = {};
}
addPlayer(player) {
// 玩家队伍颜色
const teamColor = player.teamColor;
// 根据颜色成立队伍
this.players[teamColor] = this.players[teamColor] || [];
// 将玩家添进队伍
this.players[teamColor].push(player);
}
removePlayer(player) {
const teamColor = player.teamColor;
const teamPlayers = this.players[teamColor] || [];
for (let [i, value] of teamPlayers.entries()){
if(value === player){
teamPlayers.splice(i, 1);
break;
}
}
}
changeTeam(player, newTeamColor){
this.removePlayer(player);
player.teamColor = newTeamColor;
this.addPlayer(player);
}
playerDead(player){
const teamColor = player.teamColor;
const teamPlayers = this.players[teamColor];
const isAlive = teamPlayers.some(player => player.state !== 'dead');
if(!isAlive){
teamPlayers.forEach(player => player.lose());
for (let key in this.players){
if( key === teamColor) continue;
this.players[key].forEach(player => player.win());
}
}
}
receiveMessage(message, ...rest) {
this[message](...rest);
}
}
class Player {
constructor(name, teamColor, playerDirector){
this.name = name;
this.teamColor = teamColor;
this.state = 'alive';
this.playerDirector = playerDirector;
}
win() {
console.log(this.name + ' won ');
}
lose() {
console.log(this.name + ' lost ');
}
// 玩家死亡
die() {
this.state = 'dead';
this.playerDirector.receiveMessage('playerDead', this);
}
// 移除玩家
remove() {
this.playerDirector.receiveMessage('removePlayer', this);
}
// 玩家换队
changeTeam(color){
this.playerDirector.receiveMessage('changeTeam', this, color);
}
}
// 工厂函数创建玩家,并通知中介者
const playerDirector = new PlayerDirector();
const playerFabory = function(name, teamColor) {
const newPlayer = new Player(name, teamColor, playerDirector);
playerDirector.receiveMessage('addPlayer', newPlayer);
return newPlayer;
}
const player1 = playerFabory('小王', 'red');
const player2 = playerFabory('小强', 'red');
const player3 = playerFabory('小明', 'red');
const player4 = playerFabory('大王', 'blue');
const player5 = playerFabory('大强', 'blue');
const player6 = playerFabory('大明', 'blue');
player4.changeTeam('red');
player5.remove();
player6.die();