5

已经有很多关于编写类似于 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() }
        };
    }
}

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

有什么建议吗?

4

2 回答 2

2

在 Stack Overflow 的上下文中,我想每个徽章都有以下属性:Id、Name、Class(Bronze、Silver 或 Gold)和 Description 等。

您提到您目前有一个针对每个徽章/成就的课程,每个课程都对授予它的条件进行了适当的检查。

我建议您放弃您现在正在查看的模型(每个成就一个课程)的原因是因为当您在 200 个不同的课程中寻找时,您将继续面临巨大的问题那个你记不起的ID。

通过将您的徽章存储在表格中,您的数据都在一个合乎逻辑的位置,而不是分散在您的应用程序中。

在回答问题时:您是否不同意接受的答案:stackoverflow.com/questions/3162446/

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

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

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); }
    }
}
于 2012-12-18T05:42:15.437 回答
2

使用枚举怎么样?

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

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

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

于 2012-12-18T13:22:18.583 回答