美文网首页
中介者模式

中介者模式

作者: 小宇cool | 来源:发表于2020-11-07 11:33 被阅读0次

    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来处理多个玩家之间复杂的交互, 降低了每个玩家之间的耦合性, 将复杂的交互交给了中介类进行操作,使得每个玩家类只需要注重它自身关键的部分.

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

    相关文章

      网友评论

          本文标题:中介者模式

          本文链接:https://www.haomeiwen.com/subject/vemfbktx.html