设计模式之中介者模式

什么叫中介者模式

  • 中介者模式的作用就是解除对象与对象之间的紧耦合关系
  • 增加一个中介者对象后,所有的相关对象都通过中介者对象来通信,而不是互相引用,所以当一个对象发生改变时,只需要通知中介者对象即可。
  • 承担两方面责任:中转作用,通过中介者和其他对象进行通信;协调作用,中介者可以进一步的对对象之间的关系进行封装
  • 中介者对象不能订阅消息,只有活跃对象才可订阅中介者的消息,中介者是消息的发送者

优势

  • 中介者使各对象之间耦合松散,而且可以独立地改变它们之间的交互
  • 对象之间的交互,通过中介者进行封装,集中控制交互
  • 中介者和对象一对多的关系取代了对象之间的网状多对多的关系
  • 如果对象之间的复杂耦合度导致维护很困难,而且耦合度随项目变化增速很快,就需要中介者重构代码

缺点

  • 新增一个中介者对象,如果对象间交互非常复杂,会导致中介者对象很复杂,最后往往难以维护
  • 过度集中化,中介者出现故障,导致系统瘫痪

注意事项

  • 对于对象间是网状关系的,可以采用中介者模式。
  • 感觉用处不是太大,完全可以由接口替代中介者模式

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();

复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值