2013-07-27 146 views
2

我有一個叫房類,包含所有的球員實體的屬性之一的陣列,遊戲服務器OOP設計

players = []; 

在客房類是隻返回究竟是誰參賽球員的方法全面。

// below method is called by the room's timer 

var getPlayersWhoFinished = function() { 
    playersWhoFinished = []; 
    for (i = 0; i < players.length; i++) { 
     if (players[i].isFinished()) { 
      playersWhoFinished.push(players[i]); 
     }; 
    }; 
    return playersWhoFinished; 
} 

所以我知道我可以只留下上面在客房類作爲是的,但我已經有更復雜的映射其他三個功能,在一個已經大類(300條+線)。 我不明白如何封裝這些排序方法爲其他類,因爲它們是如此密切相關的房類,所有的客房參考發送中選取適當的用戶。

修改上面的代碼並將其插入到Player類中會對我有意義,但唯一可以考慮使用此方法的方法是使用靜態方法並將空間對象發送給它。

// players is now a member of the Player class 

Player.getPlayersWhoFinished = function(room, players) { 
    playersWhoFinished = []; 
    for (i = 0; i < players; i++) { 
     if (players[i].getRoom() == room) { 
      playersWhoFinished.push(players[i]); 
     } 
    } 
    return playersWhoFinished; 
} 

無論如何,這對我來說似乎很麻煩和不合適。我一直在努力弄清楚如何讓我的Room類儘可能輕鬆。

+1

它不會真正解決你的問題,但你可以在更短的方式以'filter'重新實現這樣的過濾功能:'VAR playersWhoFinished = players.filter(功能(播放器){返回player.isFinished();} );' – icktoofay

+0

尖端,小心與那些未聲明的'i'變量,因爲它們是隱式的全局變量。 – elclanrs

+1

嗯....他們的方式,我會設計它room.getPlayersWhoFinished()將給所有玩家名單。當房間 –

回答

1

考慮分割成邏輯對象和集合。它類似於什麼主幹提供(模型,集合)。由於集合邏輯通常是特定於其包含的對象,但也具有一些共享功能(簡單迭代,過濾器等),因此您可以創建泛型集合,然後通過繼承添加更多方法以適應您的需求它存儲的特定對象的需求。

所以,你將有你的房間:

function Room() { 
    // .. 
    this.players = new PlayerCollection(); 
    // .. 
} 

收集我已經添加了一些「獎金」的方法,所以它看起來像:

function Collection() { 
    this.list = [ ]; 
    this.length = 0; 
} 

// adds item 
Collection.prototype.add = function(item) { 
    this.list.push(item); 
    this.length = this.list.length; 
} 

// removes by index 
Collection.prototype.remove = function(index) { 
    this.list.splice(index, 1); 
    this.length = this.list.length; 
} 

// finds one item based on filter function, and triggers callback with item and index 
Collection.prototype.findOne = function(fn, callback) { 
    for(var i = 0, len = this.list.length; i < len; ++i) { 
    var result = fn(this.list[i]); 
    if (result) { 
     return callback(this.list[i], i); 
    } 
    } 
    return callback(null, -1); 
} 

// filters off 
Collection.prototype.filter = function(fn) { 
    return this.list.filter(fn); 
} 

那麼就需要定義PlayerCollection,即將有額外的方法只是爲了過濾掉已完成的玩家:

function PlayerCollection() { 
    Collection.call(this); 
} 
// some inheritance here 
PlayerCollection.prototype = Object.create(Collection.prototype); 
PlayerCollection.prototype.constructor = PlayerCollection; 

// returns list of finished players 
PlayerCollection.prototype.finished = function() { 
    return Collection.prototype.filter.call(this, function(player) { 
    return player.isFinished(); 
    }); 
} 

您仍然可以重複使用即filter方法,因爲它有助於創建一些定製查詢。

你的房間邏輯看起來像:

var room = new Room(); 
// add some players to room 
// ... 
var finishedPlayers = room.players.finished(); // what you need 

它看起來清晰和直接的,同時保持所有收集的邏輯從一個房間了,所以你可以簡單地重複使用它在你的遊戲代碼。在一個地方改進 - 可以改善整體。

邏輯劃分成這樣的摘要,有助於擴大你的代碼和獨立的依賴關係。
請記住爲filter瀏覽器支持,如果你需要-IE8,然後從here得到墊片。

+0

這正是我所期待的。你向我解釋的這個概念將大大簡化我的代碼。我喜歡能夠在任何我想要的地方使用它。 – user2372427

1

getPlayersWhoFinished()方法屬於室,這是應該跟蹤玩家的對象。您還正在執行中O(n)的複雜每次你需要找到最終的球員,這可以提高時間的搜索。

你可以有一個回調的意思是在每次稱爲一個玩家完成:

Player.prototype.onFinished = function() { 
    this.getRoom().addFinished(this); 
} 

然後管理室包含了所有的成品玩家的私人陣列:

function Room() { 
    this._finishedPlayers = []; 
} 

Room.prototype.addFinished = function(player) { 
    this._finishedPlayers.push(player); 
} 

Room.prototype.getPlayersWhoFinished = function() { 
    return this._finishedPlayers; 
} 

作爲一個邊注意,你應該總是用var聲明變量,否則你會在全局範圍內聲明它們(通常是窗口對象)。