2011-11-25 42 views
2

我有一個遊戲,跟蹤每場比賽後的用戶統計數據,比如他們走了多遠,他們被攻擊了多少次,他們落了多遠等等,而我目前的實現看起來有點像下面這樣簡化版本):尋找一個合適的設計模式

Class Player{ 
    int id; 

public Player(){ 
    int id = Math.random()*100000; 
    PlayerData.players.put(id,new PlayerData()); 
} 

public void jump(){ 
    //Logic to make the user jump 
    //... 

    //call the playerManager 
    PlayerManager.jump(this); 
} 

public void attack(Player target){ 
    //logic to attack the player 
    //... 

    //call the player manager 
    PlayerManager.attack(this,target); 
} 

} 

Class PlayerData{ 
    public static HashMap<int, PlayerData> players = new HashMap<int,PlayerData>(); 
    int id; 
    int timesJumped; 
    int timesAttacked; 

} 
public void incrementJumped(){ 
    timesJumped++; 
} 
public void incrementAttacked(){ 
    timesAttacked++; 
} 

} 

Class PlayerManager{ 

public static void jump(Player player){ 
    players.get(player.getId()).incrementJumped(); 
} 
public void incrementAttacked(Player player, Player target){ 
    players.get(player.getId()).incrementAttacked(); 
} 

} 

所以我必須保持所有的統計數據,並把它從玩家級的,因爲它是不是玩家邏輯的一部分PlayerData類。然後我有PlayerManager,它將在服務器上,並且控制着玩家之間的交互(很多邏輯被排除在外,所以我可以保持這種簡單)。我把這些調用放到了Manager類的PlayerData類中,因爲有時你必須在玩家之間做一些檢查,例如,如果攻擊實際發生,那麼你會增加「attackHits」。

主要問題(在我看來,糾正我,如果我錯了)是,這是不是很可擴展。如果我想通過添加方法和字段來跟蹤新的統計信息,則必須觸摸PlayerData類,然後必須向PlayerManager添加更多方法,因此它不是非常模塊化的。

如果您對此有所改進,您會建議,我會非常感激。謝謝。

+0

你有多少種類型的玩家?如果不止一個,每種類型的玩家是否都有相同的動作? – Bhushan

+0

只有一種類型的玩家,所有人都採取相同的行動。我想稍後添加操作和統計信息的選項,因此我需要更多的可擴展性。 – user1066015

回答

4

我根本不是設計模式方面的專家。但是,這是我覺得可能是有用的:

要添加動作的球員,你可能想看看策略模式。只需谷歌,你會得到很多的例子。

這裏是我的嘗試: enter image description here

爲了更新玩家的統計,我想Observer模式會有所幫助。

觀察者模式定義了一個對多的依賴對象之間,從而 ,當一個對象改變狀態時,它的所有受撫養人被通知 和自動更新。

它強制鬆耦合,以便將來的更改很容易。

(你必須瞭解Observer模式,也必須看到一些例子,它不是直線前進的策略。)

+2

用於UML圖的+1 –

+0

正如你所說,這確實實施了鬆散耦合,因此很容易進行某些種類的更改。但在實踐中,對於遊戲而言,這種建模水平雖然準確和正確,但過於詳細。爲了添加一個新的動作,你必須在Player中實現一個新的方法,創建一個新的接口,並創建該接口的實現。所以即使聯軸器鬆動,這種變化的成本仍然很高。 – avh

0

由於你說你希望能夠增加的事實新的數據和行動後,我會傾向於製作一個統計數據對象,它不需要知道它正在記錄的遊戲的任何內容。優點是Stats類永遠不需要隨着您添加新功能而改變。

public interface Stats { 
    void incrementStat(Object subject, String stat); 
    int getStat(Object subject, String stat); 
} 

Player實施看起來是這樣的:

public void jump() { 
    // Logic to make the player jump... 

    stats.incrementStat(this, "jump"); 
} 

當然,你的交易什麼靈活性是靜態類型檢查這些增量的方法。但在這種情況下,我傾向於認爲簡單是值得的。除了從PlayerDataPlayerManager類中移除大量的鍋爐板外,最終還會生成可重用組件,並且您可以擺脫PlayerManagerPlayer之間的循環依賴關係。

+0

如何使用一個枚舉而不是String? –

+0

@SérgioMichels枚舉不可擴展。添加新的統計數據只需要改變枚舉而不是許多類,但是不能添加特殊的新數據。 – millimoose

+0

@Inddial嗯我沒有想過那:) –