中介者模式

我们知道在程序中各个对象之间并不是完全独立的,相互之间是可能存在关系的,并且可能会相互影响的,就像这样。

clipboard.png

很明显这样复杂的对象关系管理起来是很混乱的。但是如果我们把它改变成下面这个样子可能就不太一样了。

clipboard.png

即通过一个中间对象分发通知,使各个对象之间得以解耦,从混乱的多对多关系变成了对象和中介者之间的多对一关系。每当我们要新增加一个功能或者对象的时候,只需要对中介者做一些改动即可。
中介者其实就像一个航空调度员一样,如果有两架飞机凑巧航线很近,起飞降落时间也很接近的话,调度员可能就会对其中一架飞机发起通知,告诉它改变航线,或者改变降落地点,以此来避免航空事故的发生。

5v5对战

玩过LOL或者DATA的同学都知道,这是一个合作的游戏,每一个队友的生死都关系着游戏的输赢。我们要随时观察队友的状态,看看是不是少人,能否发起团战,看看队友的血量蓝量,身为辅助的队友可能要随用加血加蓝。当然这都不是最重要的,不怕神一样的对手,就怕...一样的队友,哈哈哈。

用中介者模式实现

class Player {
    constructor(name, color, status) {
        this.name = name
        this.color = color
        this.status = status
    }

    rebirth(name) {
        console.log(`${name}: rebirth`)
        agent.receiveMessage('playerRebirth', this)
    }

    die(name) {
        console.log(`${name}: died`)
        agent.receiveMessage('playerDead', this)
    }

    win() {
        console.log(`${this.name}: win`)
    }

    lose() {
        console.log(`${this.name}: lose`)
    }
}

const allPlayer = { }
const agent = {
    playerRebirth (player) {
        allPlayer[player.color] = allPlayer[player.color] || {}
        allPlayer[player.color][player.name] = player
    },
    playerDead (player) {
        allPlayer[player.color][player.name].status = 'die'
        let allDead = true
        Object.keys(allPlayer[player.color]).map((member) => {
            if (allPlayer[player.color][member].status === 'live') {
                allDead = false
            }
        })
        if (allDead) {
            Object.keys(allPlayer[player.color]).map((member) => {
                allPlayer[player.color][member].lose()
            }) 
            Object.keys(allPlayer).map((team) => {
                if (team !== player.color) {
                    Object.keys(allPlayer[team]).map((member) => {
                        allPlayer[team][member].win()
                    })
                }
            })
        }
    },

    receiveMessage() {
        const message = Array.prototype.shift.call(arguments)
        agent[message].apply(this, arguments)
    }
}

const player1 = new Player('土豆', 'red', 'live')
const player2 = new Player('馒头', 'red', 'live')
const player3 = new Player('豆包', 'blue', 'live')
const player4 = new Player('地瓜', 'blue', 'live')
player1.rebirth('土豆')
player2.rebirth('馒头')
player3.rebirth('豆包')
player4.rebirth('地瓜')
console.log(allPlayer, 'all member be ready')
player1.die('土豆')
player2.die('馒头')
console.log(allPlayer, 'one team is lose')

输出:
clipboard.png

缺陷

使用中介者模式可以很大程度上避免对象之间的相互影响,无论是对于代码的可读性以及逻辑性都可以简化。
但是不可否认的是它会创建新的对象占用一部分内存,而且这个对象随着业务逻辑的增加会变得很庞大也可能导致难以维护。


wupengyu
1.8k 声望166 粉丝

写作是为了更好的思考