11、中介者模式

1、特点

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

2、demo

泡泡堂游戏

先定义一个玩家构造函数,它有3 个简单的原型方法:Play.prototype.win、Play.prototype.lose。以及表示玩家死亡的Play.prototype.die。因为玩家的数目是2,所以当其中一个玩家死亡的时候游戏便结束, 同时通知它的对手胜利。

function Player(name, teamColor) {
    this.partners = []; // 队友列表
    this.enemies = []; // 敌人列表
    this.state = 'live'; // 玩家状态
    this.name = name; // 角色名字
    this.teamColor = teamColor; // 队伍颜色
};

Player.prototype.win = function() { // 玩家团队胜利
    console.log('winner: ' + this.name);
};

Player.prototype.lose = function() { // 玩家团队失败
    console.log('loser: ' + this.name);
};


//我们需要在每个玩家死亡的时候,都遍历其他队友的生存状况,如果队友全部死亡,则这局游戏失败,同时敌人队伍的所有玩家都取得胜利
Player.prototype.die = function() { // 玩家死亡
    var all_dead = true;
    this.state = 'dead'; // 设置玩家状态为死亡

    for (var i = 0, partner; partner = this.partners[i++];) { // 遍历队友列表
        if (partner.state !== 'dead') { // 如果还有一个队友没有死亡,则游戏还未失败
            all_dead = false;
            break;
        }
    }

    if (all_dead === true) { // 如果队友全部死亡
        this.lose(); // 通知自己游戏失败
        for (var i = 0, partner; partner = this.partners[i++];) { // 通知所有队友玩家游戏失败
            partner.lose();
        }

        for (var i = 0, enemy; enemy = this.enemies[i++];) { // 通知所有敌人游戏胜利
            enemy.win();
        }
    }
};

var playerFactory = function(name, teamColor) {
    var newPlayer = new Player(name, teamColor); // 创建新玩家

    for (var i = 0, player; player = players[i++];) { // 通知所有的玩家,有新角色加入
        if (player.teamColor === newPlayer.teamColor) { // 如果是同一队的玩家
            player.partners.push(newPlayer); // 相互添加到队友列表
            newPlayer.partners.push(player);
        } else {
            player.enemies.push(newPlayer); // 相互添加到敌人列表
            newPlayer.enemies.push(player);
        }
    }

    players.push(newPlayer);

    return newPlayer;
};

//红队:
var player1 = playerFactory('皮蛋', 'red'),
    player2 = playerFactory('小乖', 'red'),
    player3 = playerFactory('宝宝', 'red'),
    player4 = playerFactory('小强', 'red');
//蓝队:
var player5 = playerFactory('黑妞', 'blue'),
    player6 = playerFactory('葱头', 'blue'),
    player7 = playerFactory('胖墩', 'blue'),
    player8 = playerFactory('海盗', 'blue');

// 让红队玩家全部死亡:
player1.die();
player2.die();
player4.die();
player3.die();

现在我们已经可以随意地为游戏增加玩家或者队伍,但问题是,每个玩家和其他玩家都是紧
紧耦合在一起的。在此段代码中,每个玩家对象都有两个属性,this.partners 和this.enemies,
用来保存其他玩家对象的引用。当每个对象的状态发生改变,比如角色移动、吃到道具或者死亡
时,都必须要显式地遍历通知其他对象。

用中介者模式改造泡泡堂游戏

现在我们开始用中介者模式来改造上面的泡泡堂游戏, 改造后的玩家对象和中介者的关系

首先仍然是定义Player 构造函数和player 对象的原型方法,在player 对象的这些原型方法中,不再负责具体的执行逻辑,而是把操作转交给中介者对象,我们把中介者对象命名为playerDirector。

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.reciveMessage('playerDead', this); // 给中介者发送消息,玩家死亡
};

/*******************移除玩家*****************/
Player.prototype.remove = function() {
    playerDirector.reciveMessage('removePlayer', this); // 给中介者发送消息,移除一个玩家
};

/*******************玩家换队*****************/
Player.prototype.changeTeam = function(color) {
    playerDirector.reciveMessage('changeTeam', this, color); // 给中介者发送消息,玩家换队
};

var playerFactory = function(name, teamColor) {
    var newPlayer = new Player(name, teamColor); // 创造一个新的玩家对象
    playerDirector.reciveMessage('addPlayer', newPlayer); // 给中介者发送消息,新增玩家
    return newPlayer;
};

//玩家对象, 代码如下:
var playerDirector = (function() {
    var players = {}, // 保存所有玩家
        operations = {}; // 中介者可以执行的操作
    /****************新增一个玩家***************************/
    operations.addPlayer = function(player) {
        var teamColor = player.teamColor; // 玩家的队伍颜色
        players[teamColor] = players[teamColor] || []; // 如果该颜色的玩家还没有成立队伍,则
        //新成立一个队伍
        players[teamColor].push(player); // 添加玩家进队伍
    };
    /****************移除一个玩家***************************/
    operations.removePlayer = function(player) {
        var teamColor = player.teamColor, // 玩家的队伍颜色
            teamPlayers = players[teamColor] || []; // 该队伍所有成员
        for (var 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) { // 玩家死亡
        var teamColor = player.teamColor,
            teamPlayers = players[teamColor]; // 玩家所在队伍
        var all_dead = true;
        for (var i = 0, player; player = teamPlayers[i++];) {
            if (player.state !== 'dead') {
                all_dead = false;
                break;
            }
        }
        if (all_dead === true) { // 全部死亡
            for (var i = 0, player; player = teamPlayers[i++];) {
                player.lose(); // 本队所有玩家lose
            }
            for (var color in players) {
                if (color !== teamColor) {
                    var teamPlayers = players[color]; // 其他队伍的玩家
                    for (var i = 0, player; player = teamPlayers[i++];) {
                        player.win(); // 其他队伍所有玩家win
                    }
                }
            }
        }
    };

    var reciveMessage = function() {
        var message = Array.prototype.shift.call(arguments); // arguments 的第一个参数为消息名称

        operations[message].apply(this, arguments);
    };

    return {
        reciveMessage: reciveMessage
    }
})();

// 红队:
var player1 = playerFactory('皮蛋', 'red'),
    player2 = playerFactory('小乖', 'red'),
    player3 = playerFactory('宝宝', 'red'),
    player4 = playerFactory('小强', 'red');
// 蓝队:
var player5 = playerFactory('黑妞', 'blue'),
    player6 = playerFactory('葱头', 'blue'),
    player7 = playerFactory('胖墩', 'blue'),
    player8 = playerFactory('海盗', 'blue');

player1.die();
player2.die();
player3.die();
player4.die();

参考文献:《JavaScript设计模式与开发实践》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是常见的Java设计模式: 1. 工厂模式(Factory Pattern) 2. 单例模式(Singleton Pattern) 3. 建造者模式(Builder Pattern) 4. 原型模式(Prototype Pattern) 5. 适配器模式(Adapter Pattern) 6. 桥接模式(Bridge Pattern) 7. 组合模式(Composite Pattern) 8. 装饰器模式(Decorator Pattern) 9. 外观模式(Facade Pattern) 10. 享元模式(Flyweight Pattern) 11. 代理模式(Proxy Pattern) 12. 观察者模式(Observer Pattern) 13. 中介者模式(Mediator Pattern) 14. 命令模式(Command Pattern) 15. 访问者模式(Visitor Pattern) 16. 解释器模式(Interpreter Pattern) 17. 迭代器模式(Iterator Pattern) 18. 策略模式(Strategy Pattern) 19. 模板方法模式(Template Method Pattern) 20. 职责链模式(Chain of Responsibility Pattern) 21. State 模式(状态模式) 22. Memento 模式(备忘录模式) 23. Builder 模式(建造者模式) 24. Composite 模式(组合模式) 25. Command 模式(命令模式) 26. Adapter 模式(适配器模式) 27. Proxy 模式(代理模式) 28. Bridge 模式(桥接模式) 29. Decorator 模式(装饰器模式) 30. Facade 模式(外观模式) 31. Flyweight 模式(享元模式) 32. Interpreter 模式(解释器模式) 33. Iterator 模式(迭代器模式) 34. Mediator 模式(中介者模式) 35. Memento 模式(备忘录模式) 36. Observer 模式(观察者模式) 37. Prototype 模式(原型模式) 38. Singleton 模式(单例模式) 39. Strategy 模式(策略模式) 40. Template Method 模式(模板方法模式) 41. Visitor 模式(访问者模式)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值