设计模式之中介者模式

2018-05-16  本文已影响0人  GrowthCoder

什么叫中介者模式

优势

zjz2.png zjz.png

缺点

注意事项

vs 发布-订阅模式

即使有中介者,A和B存在某种联系,因为有联系,为了避免A与更多其他的对象有直接的联系,才诞生出来了中介者,一对多变成了一对一。

发布-订阅模式,有时候也会找个对象统一管理,A订阅了事件和B订阅了事件,但是A和B之间是没有什么联系的。

泡泡糖游戏实例

class Player {
    constructor(name, teamColor) {
        this.name = name;
        this.teamColor = teamColor;
        this.state = 'alive';
    }
    win () {
        console.log(this.name, 'win');
    }

    lose () {
        console.log(this.name, 'lose');
    }

    die () {
        this.state = 'dead';
        playerDirector.receiveMessage('playerDead', this);
    }
    remove () {
        playerDirector.reciveMessage('removePlayer', this);
    }

    changeTeam (color) {
        playerDirector.receiveMessage('changeTeam', this, color);
    }
}

// 工厂创建玩家
const playerFactor = (name, teamColor) => {
    const newPlayer = new Player(name, teamColor);
    playerDirector.receiveMessage('addPlayer', newPlayer);
    return newPlayer;
}

// 中介者
const playerDirector = (() => {
    const players = {},
    operations = {};

    // 新增
        operations.addPlayer = (player) => {
            const teamColor = player.teamColor;

            players[teamColor] = players[teamColor] || [];

            players[teamColor].push(player);
    };

    // 移除
    operations.removePlayer = (player) => {
      const teamColor = player.teamColor,
        teamPlayers = players[teamColor] || [];

        teamPlayers = teamPlayers.filter(item => item == player);
    }

    // 换队
    operations.changeTeam = (player, newTeamColor) => {
      operations.removePlayer(player);
      player.teamColor = newTeamColor;
      operations.addPlayer(player);
    }
    // 玩家死亡
    operations.playerDead = (player) => {
      const teamColor = player.teamColor,
        teamPlayers = players[ teamColor ];
      
      let allDead = !teamPlayers.some(item => item.state !== 'dead');

      if(allDead ) {
        teamPlayers.forEach(item => {
          item.lose();
        })
        
        for(color in players) {
          if(color !== player.teamColor) {
            const winTeam = players[color];

            winTeam.forEach(item => {
              item.win();
            })
          }
        }
      }
    }

    // 暴漏接口
    const receiveMessage = function () {
      const message = Array.prototype.shift.call(arguments);
      operations[message].apply(this, arguments);
    }
    
    return {
      receiveMessage: receiveMessage
    }
})();

const player1 = playerFactor('红1', 'red');
const player2 = playerFactor('蓝1', 'blue');
const player3 = playerFactor('蓝2', 'blue');
player1.die();

上一篇下一篇

猜你喜欢

热点阅读