《JavaScript設計模式與開發實踐》讀書筆記之中介者模式

來源:互聯網
上載者:User

標籤:

1. 中介者模式

中介者模式的作用就是用來解除對象與對象之間的緊耦合關係,增加中介者後,所有相關對象都通過中介者來通訊,而不再相互引用

1.1中介者模式的例子

以泡泡堂遊戲為例,先定義一個玩家建構函式,它有三個原型方法

Player.prototype.win,Player.prototype.lose,Player.prototype.die

 

當只有兩個玩家時,一個玩家死亡時遊戲結束,同時通知他的對手勝利

function Player(name){    this.name=name;    this.enemy=null;}Player.prototype.win=function(){    console.log(this.name+‘won‘);};Player.prototype.lose=function(){    console.log(this.name+‘lose‘);};Player.prototype.die=function(){    console.log(this.name+‘die‘);};

接下來建立兩個玩家

var player1=new Player(‘玩家1‘);var player2=new Player(‘玩家2‘);//設定敵人player1.enemy=player2;player2.enemy=player1;//玩家1死亡時,調用自己的die方法完成一局遊戲player1.die();

 

當玩家增加時,每個玩家有了自己的隊友和若干敵人

定義一個數組players儲存所有的玩家,建立玩家之後,迴圈players來給每個玩家設定敵人和隊友

var players=[];

再改寫建構函式Player,使每個玩家對象都增加一些屬性,分別是隊友列表、敵人列表、玩家目前狀態、角色名稱字以及玩家所在隊伍的顏色

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;};

用這段代碼來建立8個玩家,分屬紅藍兩隊

var player1=playerFactory(‘p1‘,‘red‘);var player2=playerFactory(‘p2‘,‘red‘);var player3=playerFactory(‘p3‘,‘red‘);var player4=playerFactory(‘p4‘,‘red‘);var player5=playerFactory(‘p5‘,‘blue‘);var player6=playerFactory(‘p6‘,‘blue‘);var player7=playerFactory(‘p7‘,‘blue‘);var player8=playerFactory(‘p8‘,‘blue‘);

讓紅隊全部死亡

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

此時藍隊玩家勝利

1.2 用中介者模式改造上述樣本

上述樣本中,每個玩家和其他玩家都是緊耦合在一起,partners,enemies儲存著其他玩家對象的引用。當對象狀態改變,如死亡時,必須顯示遍曆通知其他玩家

 首先仍然是定義Player建構函式和player對象的原型方法

function Player(name,teamColor){    this.name=name;    this.teamColor=teamColor;    this.state=state;};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.ReceiveMessage(‘playerDead‘,this);};//移除玩家Player.prototype.remove=function(){    playerDirector.ReceiveMessage(‘removePlayer‘,this);};//玩家換隊Player.prototype.changeTeam=function(color){    playerDirector.ReceiveMessage(‘changeTeam‘,this,color);};

改寫建立玩家對象的工廠函數

var playerFactory=function(name,teamColor){    var newPlayer=new Player(name,teamColor);    playerDirector.ReceiveMessage(‘addPlayer‘,newPlayer);    return newPlayer;};

playerDirector開放一個對外暴露的介面ReceiveMessage,負責接收player對象發送的訊息,
而player對象發送的時候,總是把自身this作為參數發送給playDirector,以便playerDirector識別訊息來自於哪個玩家對象

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();            }                        for(var color in players){                if(color !== teamColor){                    var teamPlayers=players[color];//對手玩家                    for(var i=0,player;player=teamPlayers[i++];){                        player.win();                    }                                    }            }        }    }        var ReceiveMessage=function(){        var message=Array.prototype.shift.call(arguments);        operations[message].apply(this,arguments);    };        return{        ReceiveMessage:ReceiveMessage    }})();

現在除了中介者本身,沒有一個玩家知道其他玩家的存在,玩家與玩家之間的耦合關係已經解除

某個玩家的任何操作不需要通知其他買家,只需要給中介者發送一個訊息

中介者處理完訊息之後,把處理結果反饋給其他玩家

《JavaScript設計模式與開發實踐》讀書筆記之中介者模式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.