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