设计模式-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();
posted @ 2023-03-13 14:41  箫笛  阅读(35)  评论(0编辑  收藏  举报