中介者模式

解除对象与对象之间的紧耦合关系。
生活中场景:机场指挥塔。

  • 泡泡堂游戏
  1. 定义数组保存所有的玩家
var players = [];
  1. 构造函数,创建玩家,增加属性。
function Player( name, teamColor ){
    this.partners = []; // 队友列表
    this.enemies = []; // 敌人列表
    this.state = 'live'; // 玩家状态
    this.name = name; // 角色名字
    this.teamColor = teamColor; // 队伍颜色
};
  1. 增加胜利和失败的原型方法
Player.prototype.win = function(){ // 玩家团队胜利
    console.log( 'winner: ' + this.name );
};

Player.prototype.lose = function(){ // 玩家团队失败
    console.log( 'loser: ' + this.name );
};
  1. 玩家死亡方法,要判断队友的状态
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();
        }
    }
};
  1. 创建一个新玩家后,要找到队友和敌人,所以定义一个工厂来创建玩家。
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;
};

上述缺点:主要体现在第5步,每创建一个玩家,都要遍历所有的玩家,然后相互添加为队友或敌人。
每个玩家紧耦合在一起。并且不容易增加新功能,比如玩家换队。

  • 使用中介者模式改造
  1. 构造函数,不再执行具体逻辑。
function Player( name, teamColor ){
    this.name = name; // 角色名字
    this.teamColor = teamColor; // 队伍颜色
    this.state = 'alive'; // 玩家生存状态
};
  1. 原型方法,请求转交给中介者处理。
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 ); // 给中介者发送消息,玩家换队
};
  1. 工厂函数作用和之前一样。
var playerFactory = function( name, teamColor ){
    var newPlayer = new Player( name, teamColor ); 
    playerDirector.ReciveMessage( 'addPlayer', this ); 
    return newPlayer;
};
  1. 定义中介者playerDirector , 从上面可以看出,需要暴露接口ReceiveMessage
var playerDirector= ( function(){
    var players = {}, // 保存所有玩家
        operations = {}; // 中介者可以执行的操作
   
    operations.addPlayer = function( player ){
        // ...
    };

    operations.removePlayer = function( player ){
        //...
    };

    operations.changeTeam = function( player, newTeamColor ){ 
        // ..
    };

    operations.playerDead = function( player ){ 
        // ...
    };

    var reciveMessage = function(){
        var message = Array.prototype.shift.call( arguments ); // arguments 的第一个参数为消息名称
        operations[ message ].apply( this, arguments );
    };

    return {
        reciveMessage: reciveMessage
    }

})();

优点:玩家之间耦合解除。某个玩家的操作,只需通知中介者,中介者处理后再反馈给其他玩家。

  • 购买商品例子

你可能感兴趣的:(中介者模式)