中介者模式

2020-11-07  本文已影响0人  小宇cool

1. 中介者模式

1.1 定义

中介者模式(Mediator):通过中介者对象封装一系列对象之间的交互,使对象之间不再相互引用,降低他们之间的耦合

我们可以理想到房屋中介, 假如有很多人需要买房租房, 有很多人需要卖房或者出租,还有的人需要买房然后买个更大的房.这时候如果买家和卖家之间相互沟通,那不仅费时费力,并且还不一定找的到最满意最合适的.此时房屋中介的作用就体现出来了. 中介者模式就是解决多个对象之间的交互问题, 只需要访问一个中介.就可以解决所有的问题,把多对复杂的问题变成一对多相对简单的问题

1.2作用

  1. 解决多个对象之间的复杂交互问题, 降低对象和对象之间的耦合.
  2. 降低类的复杂度,将一对多转换为一对一.实现各个类的解耦.

1.3 应用场景

class Player{
    constructor(name){
        this.name = name;
        this.enemy = null;
    }
    win(){
        console.log(this.name + '胜利')
    }
    lose(){
        console.log(this.name + '失败')
    }
    die(){
        this.lose();
        this.enemy.win();
    }
}
let player1 = new  Player('小明');
let player2 = new Player('张三');
player1.enemy = player2;
player2.enemy = player1;
player1.die()
//张三失败
// 小明胜利

上面代码定义了一个玩家类,并为其指定了三个方法,当玩家实例A或者玩家实例B其中一个实例触发了die事件,此时该实例触发lose事件, 另一个实例触发对应的win事件.但上面玩家类实例我们的手动为其指定对应的敌对实例, 耦合性很强, 但我们有非常的多的玩家实例时, 此时我们手动指定对应的敌对实例起来非常麻烦,当我们需要扩展需求多人组队一起游戏时,此时使用中介者模式就非常合适.

// 玩家类
class Player{
    constructor(name,teamName){
        // 记录玩家需要储存的信息
        this.name = name;
        this.live = true;
        this.teamName = teamName;
        // 其他信息( 队友 敌人) 全部由中介这者处理
        playerMediator.addPlayer(this)
    }
    // 胜利
    win(){
        console.log(this.name + '胜利')
    }
    // 失败
    lose(){
        console.log(this.name + '失败')
    }
    // 死亡
    die(){
        //自身存活状态发生改变
        this.live = false
        // 告知中介者 , 做后续处理
        playerMediator.playerDie(this)
    }
}
// 中介者
let playerMediator = (function(){
    // 队伍玩家信息
    let teamInfo = {},// 保存队伍玩家信息
        teamList = [];// 保存队伍的name
    return {
        //浏览队伍所有信息
        reviewInfo(){
            console.log(teamInfo)
        },
        // 玩家加入
        addPlayer(player){
            let teamName = player.teamName
            if(!teamInfo[teamName]){
                teamInfo[teamName] = [];
                teamList.push(teamName)
            }
            teamInfo[teamName].push(player)
        },
        // 玩家阵亡
        playerDie(player){
            // 获取玩家所处队伍的信息
            let team = teamInfo[player.teamName];
           // 检测玩家所在队伍是否全部阵亡, 如果全部阵亡则返回true
           let isAllDie = team.every(p => p.live === false);
           // 假设全部阵亡
            if(isAllDie){
                //该对触发lose信息
               team.forEach(p => p.lose());
               // 从teamList 删除该队信息
              teamList.splice(teamList.indexOf(player.teamName),1);
                //检测是否只剩下一队 当只剩下一对时触发 win方法
               if(teamList.length === 1) {
                  let winTeamName = teamList[0];
                  teamInfo[winTeamName].forEach(p => p.win())
               }
            }
        }
    }
})()
let p1 = new Player("小明","red");
let p2 = new Player("小白","red");
let p3 = new Player("张一","green");
let p4 = new Player("张二","green");
let p5 = new Player("张三","green");
let p6 = new Player("李一","blue");
let p7 = new Player("李二","blue");
let p8 = new Player("李三","blue");
p1.die()
p2.die()
p3.die()
p4.die();
p5.die();
playerMediator.reviewInfo();
// 此时我们可以可以在控制台打印出如下信息
/*
    小明失败
    小白失败
    张一失败
    张二失败
    张三失败
    李一胜利
    李二胜利
    李三胜利    
    {
  red: [
    Player { name: '小明', live: false, teamName: 'red' },
    Player { name: '小白', live: false, teamName: 'red' }
  ],
  green: [
    Player { name: '张一', live: false, teamName: 'green' },
    Player { name: '张二', live: false, teamName: 'green' },
    Player { name: '张三', live: false, teamName: 'green' }
  ],
  blue: [
    Player { name: '李一', live: true, teamName: 'blue' },
    Player { name: '李二', live: true, teamName: 'blue' },
    Player { name: '李三', live: true, teamName: 'blue' }
  ]
}
*/

我们通过中介类playerMediator来处理多个玩家之间复杂的交互, 降低了每个玩家之间的耦合性, 将复杂的交互交给了中介类进行操作,使得每个玩家类只需要注重它自身关键的部分.

总结: 中介者模式主要用来解决多个对象之间的通信复杂性, 这个模式通过中介类.来处理多个类之间的通信,使得代码变得易于维护. 当应用程序中对象之间存在比较复杂的引用关系是, 导致它们之间的依赖关系结构混乱,此时使用中介者模式非常合适.

上一篇下一篇

猜你喜欢

热点阅读