寻找合适的设计模式

时间:2011-11-25 17:46:55

标签: java design-patterns

我有一款游戏可以跟踪每次比赛后的用户统计数据,例如他们走过的距离,他们攻击的次数,他们跌落的距离等,以及我目前的实施情况如下(简化版):

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添加更多方法,因此它不是非常模块化的。

如果您对此有所改进,我会非常感激。感谢。

2 个答案:

答案 0 :(得分:4)

我根本不是设计模式方面的专家。但这是我认为可能有用的东西:

要向播放器添加操作,您可能需要查看策略模式。只是google for it,你会得到很多例子。

以下是我的尝试: enter image description here

为了更新玩家统计数据,我猜观察者模式会有所帮助。

  

观察者模式定义了对象之间的一对多依赖关系   当一个对象改变状态时,将通知其所有依赖者   并自动更新。

它强制执行松散耦合,以便将来的更改变得容易。

(你必须阅读Observer Pattern,还必须看一些例子。它不像Strategy那么直接。)

答案 1 :(得分: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类中删除大量锅炉板之外,您还最终得到了一个可重用的组件,您可以摆脱PlayerManager和{{之间的循环依赖关系。 1}}。