2013-07-27 2 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 + 라인)가 있습니다. 이러한 클래스를 다른 클래스에 캡슐화하는 방법을 알지 못합니다. 클래스가 Room 클래스 및 모든 Room 참조와 밀접한 관련이 있으므로 적절한 사용자에게 보내야합니다.

위의 코드를 수정하여 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 (function player {return player.isFinished();}); ' – icktoofay

+0

팁, 암묵적인 전역 변수이므로 선언되지 않은'i' 변수에주의하십시오. – elclanrs

+1

흠 .... .... 나는 그들이 방을 만들었을 것이라고 생각했다 .getPlayersWhoFinished()는 모든 플레이어에게 줄 것이다. 방이 방 –

답변

1

논리를 개체와 컬렉션으로 나누는 것을 고려하십시오. 백본이 제공하는 것과 유사합니다 (모델, 컬렉션).

컬렉션 로직은 일반적으로 포함되어 있지만 공유 기능 (간단한 반복, 필터 등)을 가지고 있기 때문에 일반적인 컬렉션을 만들고 상속을 통해 더 많은 메소드를 추가하여 그것이 저장하는 특정 객체의 필요성. 것처럼 보일 것이다, 그래서 나는 약간의 '보너스'방법을 추가 한 컬렉션

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

: 당신이 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); 
} 

것으로,

그래서 당신은 당신의 방을 가질 것 완료된 플레이어를 걸러 낼 수있는 특별한 방법이 있습니다 :

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이 필요한 경우 sh30을 here에서 가져 오십시오.

+0

이것은 정확히 내가 찾고있는 것입니다. 이 개념을 설명하면 코드가 크게 단순 해집니다. 내가 원하는 곳 어디에서나 사용할 수있는 것을 좋아한다. – user2372427

1

getPlayersWhoFinished() 메서드는 Room에 속하며, 이는 플레이어를 추적해야하는 개체입니다. 완성 된 플레이어를 찾아야 할 때마다 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로 선언해야합니다. 그렇지 않으면 전역 범위 (예 : 일반적으로 윈도우 객체)에서 선언하게됩니다.