成就/徽章的架构

Tes*_*rex 5 c# architecture asp.net-mvc achievements

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

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

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

public int Key { get { return 15; } } // I'm calling it Key, not ID
Run Code Online (Sandbox Code Playgroud)

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

我可以把它们放在另一堂课的一些字典里......

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

    public AchievementSet()
    {
        _achievements = new Dictionary<int, Achievement>()
        {
            { 1, new SomethingAchievement() }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

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

有什么建议?

Jos*_*rty 2

在 Stack Overflow 的上下文中,我想象每个徽章都具有以下属性:ID、名称、类别(铜牌、银牌或金牌)和描述等。

您提到您目前为每个徽章/成就都有一个类别,每个类别都会对授予该徽章/成就的条件进行适当的检查。

我建议你放弃现在正在使用的模型(每个成就一个类别)的原因是,当你在 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}
}
Run Code Online (Sandbox Code Playgroud)

我将修改他的代码如下:

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); }
    }
}
Run Code Online (Sandbox Code Playgroud)