JavaScript设计模式-中介者模式

概念

  1. 中介者模式的作用就是解除对象与对象之间的紧耦合关系。增加一个中介者对象后,所有的相关对象都通过中介者对象来通信,而不是互相引用,所以当一个对象发生改变时,只需要通知中介者对象即可。中介者使各对象之间耦合松散,而且可以独立地改变它们之间的交互。中介者模式使网状的多对多关系变成了相对简单的一对多关系。

例子

// 1.定义一个中介者, 用来统一处理所有玩家的交互行为
const playerDirector = (function () {
    const players = {} // 保存所有玩家
    const operations = {} // 中介者可以执行的操作
    /****************新增一个玩家***************************/
    operations.addPlayer = function (player) {
        const teamColor = player.teamColor // 玩家的队伍颜色
        players[teamColor] = players[teamColor] || [] // 如果该颜色的玩家还没有成立队伍,则
        // 新成立一个队伍
        players[teamColor].push(player) // 添加玩家进队伍
    }
    /****************移除一个玩家***************************/
    operations.removePlayer = function (player) {
        const teamColor = player.teamColor, // 玩家的队伍颜色
            teamPlayers = players[teamColor] || [] // 该队伍所有成员
        for (let i = teamPlayers.length - 1; i >= 0; i--) { // 遍历删除
            if (teamPlayers[i] === player) {
                teamPlayers.splice(i, 1)
            }
        }
    }
    /****************玩家换队***************************/
    operations.changeTeam = function (player, newTeamColor) { // 玩家换队
        operations.removePlayer(player) // 从原队伍中删除
        player.teamColor = newTeamColor // 改变队伍颜色
        operations.addPlayer(player) // 增加到新队伍中
    }
    /****************玩家死亡***************************/
    operations.playerDead = function (player) {
        // 玩家死亡
        const teamColor = player.teamColor
        const teamPlayers = players[teamColor] // 玩家所在队伍
        let all_dead = true
        for (let i = 0; i < teamPlayers.length; i ++) { // 单人死亡不影响其他玩家
            if (teamPlayers[i].state !== 'dead') {
                all_dead = false
                break
            }
        }
        // 全部死亡通知其他队伍的玩家赢了
        if (all_dead === true) { // 全部死亡
            for (let i = 0; i < teamPlayers.length; i ++) {
                teamPlayers[i].lose() // 本队所有玩家lose
            }
            for (let color in players) {
                if (color !== teamColor) {
                    const orderTeamPlayers = players[color] // 其他队伍的玩家
                    for (let i = 0; i < orderTeamPlayers.length; i ++) {
                        orderTeamPlayers[i].win() // 其他队伍所有玩家win
                    }
                }
            }
        }
    }
    // 暴露在外面的调用方法,接收一个方法名,已经需要传递的参数
    const ReceiveMessage = function (funName, ...args) {
        operations[funName].apply(this, args)
    }
    return {
        ReceiveMessage: ReceiveMessage
    }
})()

// 2.定义玩家,有哪些属性
function Player (name, teamColor) {
    this.name = name // 角色名字
    this.teamColor = teamColor // 队伍颜色
    this.state = 'alive' // 玩家生存状态
}
// 玩家行为,用来处理个体的行为
Player.prototype.win = function () {
    console.log(this.name + ' won ')
}
Player.prototype.lose = function () {
    console.log(this.name + ' lost')
}
/*******************玩家死亡*****************/
Player.prototype.die = function () {
    this.state = 'dead'
    playerDirector.ReceiveMessage('playerDead', this) // 给中介者发送消息,玩家死亡
}
/*******************移除玩家*****************/
Player.prototype.remove = function () {
    playerDirector.ReceiveMessage('removePlayer', this) // 给中介者发送消息,移除一个玩家
}
/*******************玩家换队*****************/
Player.prototype.changeTeam = function (color) {
    playerDirector.ReceiveMessage('changeTeam', this, color) // 给中介者发送消息,玩家换队
}

// 3.外部访问的入口
const playerFactory = function (name, teamColor) {
    const newPlayer = new Player(name, teamColor) // 创造一个新的玩家对象
    playerDirector.ReceiveMessage('addPlayer', newPlayer) // 给中介者发送消息,新增玩家
    return newPlayer
}

export default playerFactory

总结

  1. 中介者模式是迎合迪米特法则的一种实现。迪米特法则也叫最少知识原则,是指一个对象应该尽可能少地了解另外的对象(类似不和陌生人说话)。如果对象之间的耦合性太高,一个对象发生改变之后,难免会影响到其他的对象,跟“城门失火,殃及池鱼”的道理是一样的。而在中介者模式里,对象之间几乎不知道彼此的存在,它们只能通过中介者对象来互相影响对方。
  2. 好处:中介者模式使各个对象之间得以解耦,以中介者和对象之间的一对多关系取代了对象 之间的网状多对多关系。各个对象只需关注自身功能的实现,对象之间的交互关系交给了中介者对象来实现和维护。
  3. 缺点:中介者模式也存在一些缺点。其中,最大的缺点是系统中会新增一个中介者对象,因 为对象之间交互的复杂性,转移成了中介者对象的复杂性,使得中介者对象经常是巨大的。中介者对象自身往往就是一个难以维护的对象。

github仓库地址:点击 设计模式例子 查看

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值