解除對象與對象之間的緊耦合關(guān)系厌衔。
生活中場景:機場指揮塔。
- 泡泡堂游戲
- 定義數(shù)組保存所有的玩家
var players = [];
- 構(gòu)造函數(shù)捍岳,創(chuàng)建玩家富寿,增加屬性。
function Player( name, teamColor ){
this.partners = []; // 隊友列表
this.enemies = []; // 敵人列表
this.state = 'live'; // 玩家狀態(tài)
this.name = name; // 角色名字
this.teamColor = teamColor; // 隊伍顏色
};
- 增加勝利和失敗的原型方法
Player.prototype.win = function(){ // 玩家團隊勝利
console.log( 'winner: ' + this.name );
};
Player.prototype.lose = function(){ // 玩家團隊失敗
console.log( 'loser: ' + this.name );
};
- 玩家死亡方法锣夹,要判斷隊友的狀態(tài)
Player.prototype.die = function(){ // 玩家死亡
var all_dead = true;
this.state = 'dead'; // 設(shè)置玩家狀態(tài)為死亡
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();
}
}
};
- 創(chuàng)建一個新玩家后,要找到隊友和敵人晕城,所以定義一個工廠來創(chuàng)建玩家泞坦。
var playerFactory = function( name, teamColor ){
var newPlayer = new Player( name, teamColor ); // 創(chuàng)建新玩家
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;
};
上述缺點:主要體現(xiàn)在第5步砖顷,每創(chuàng)建一個玩家贰锁,都要遍歷所有的玩家,然后相互添加為隊友或敵人滤蝠。
每個玩家緊耦合在一起豌熄。并且不容易增加新功能,比如玩家換隊物咳。
- 使用中介者模式改造
- 構(gòu)造函數(shù)锣险,不再執(zhí)行具體邏輯。
function Player( name, teamColor ){
this.name = name; // 角色名字
this.teamColor = teamColor; // 隊伍顏色
this.state = 'alive'; // 玩家生存狀態(tài)
};
- 原型方法览闰,請求轉(zhuǎn)交給中介者處理芯肤。
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 ); // 給中介者發(fā)送消息,玩家死亡
};
/*******************移除玩家*****************/
Player.prototype.remove = function(){
playerDirector.reciveMessage( 'removePlayer', this ); // 給中介者發(fā)送消息压鉴,移除一個玩家
};
/*******************玩家換隊*****************/
Player.prototype.changeTeam = function( color ){
playerDirector.reciveMessage( 'changeTeam', this, color ); // 給中介者發(fā)送消息崖咨,玩家換隊
};
- 工廠函數(shù)作用和之前一樣。
var playerFactory = function( name, teamColor ){
var newPlayer = new Player( name, teamColor );
playerDirector.ReciveMessage( 'addPlayer', this );
return newPlayer;
};
- 定義中介者
playerDirector
, 從上面可以看出油吭,需要暴露接口ReceiveMessage
var playerDirector= ( function(){
var players = {}, // 保存所有玩家
operations = {}; // 中介者可以執(zhí)行的操作
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 的第一個參數(shù)為消息名稱
operations[ message ].apply( this, arguments );
};
return {
reciveMessage: reciveMessage
}
})();
優(yōu)點:玩家之間耦合解除击蹲。某個玩家的操作署拟,只需通知中介者,中介者處理后再反饋給其他玩家歌豺。
- 購買商品例子