成就/徽章的架构

时间:2012-12-18 04:29:39

标签: c# asp.net-mvc architecture achievements

关于编码类似于SO的徽章系统已经有很多问题,我的问题是不同的。假设我有一个网页系统,徽章/成​​就,作为一行存储在数据库中,包含成就键(id),用户ID和任何其他数据。

我的简单问题是,我应该在哪里存储徽章ID?我每个成就都有一个课程,所有数据和测试方法是否已经获得。我想我在某些时候可能会有几十个或几百个。我希望ID只能用硬编码一次,并且在一个简洁的地方,所以我没有机会不小心改变它们或将它们混合起来。

我可以在课堂上对它们进行硬编码,比如

public int Key { get { return 15; } } // I'm calling it Key, not ID

但如果我在多个文件中分割我的成就,我不想在添加新密钥时查找最高密钥并且冒着错误。

我可以将它们放在另一个班级的一些字典中......

public class AchievementSet
{
    private Dictionary<int, Achievement> _achievements;

    public AchievementSet()
    {
        _achievements = new Dictionary<int, Achievement>()
        {
            { 1, new SomethingAchievement() }
        };
    }
}

但是现在这个类本身并不知道它自己的键,它需要(或者它是什么?)如果我将它传递给构造函数,那么我冒着与数字不匹配的风险。

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

在Stack Overflow的上下文中,我想每个徽章都有以下属性: Id,Name,Class(青铜,银或金)和描述等。

您提到您目前每个徽章/成就都有一个班级,每个班级都有适当的检查条件。

我建议你离开你现在正在看的模型(每个成就一个班级)的原因是因为当你在200个不同的航线中航行时,你将继续面临巨大的问题寻找那个你无法回忆的ID的课程。

通过将徽章存储在表格中,您的数据全部位于一个逻辑位置,而不会分散在您的应用程序中。

回答这个问题:你是否不同意接受的答案:stackoverflow.com/questions/3162446/

不一定,我更喜欢这个想法,而不是我之前提出的关于根据他们的ID检查所有徽章的单个类的建议。

尽管它的名字,我相信RexM没有在该文件中定义CommenterBadge本身,并且应该将其命名为CommenterBadgeJob。 (你会注意到它没有我在答案中定义的特征,并且继承自BadgeJob)。显而易见的问题是“每个徽章工作如何知道它对应哪个徽章?”

我的Badge中还有一个名为BadgeJob的唯一字段,您可以通过该字段查找徽章。

enum BadgeClass {Bronze, Silver, Gold}

//This class would be inherited from the database.
public class Badge
{
    public int Key {get;set;}
    public string Name {get;set;}
    public BadgeClass Class {get;set;}
    public string BadgeJob {get;set;}
    public string Description {get;set}
}

我会修改他的代码如下:

public class CommenterBadgeJob : BadgeJob
{
    public Badge commenter_badge {get;set;}
    public CommenterBadgeJob() : base() 
    {
        //Lookup badge
        string badge_job_name = this.GetType().Name;
        commenter_badge  = db.Badges.Where(n=>n.BadgeJob == badge_job_name).Single();
    }

    protected override void AwardBadges()
    {
        //select all users who have more than x comments 
        //and dont have the commenter badge
        //add badges
    }

    //run every 10 minutes
    protected override TimeSpan Interval
    {
        get { return new TimeSpan(0,10,0); }
    }
}

答案 1 :(得分:2)

如何使用枚举?

  public enum BadgeTypes
  {
      GoodAnswer    = 1,
      Commenter     = 2,
      Teacher       = 3,
      //...
  }

每个BadgeJob都可以有BadgeType属性,用于在AwardBadges()期间插入成就时填充徽章ID(枚举值可以保留为整数)。

我认为没有必要为每个成就设一门课。 BadgeJob包含所有徽章归因逻辑,BadgeTypes足以代表不同的徽章。