Архитектура для достижений / значков
Уже много вопросов о кодировании системы бейджей, аналогичной SO, мой вопрос другой. Предположим, у меня есть система веб-страниц, значки / достижения, хранящиеся в БД в виде строки с ключом достижения (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 ответа
В контексте переполнения стека, я бы предположил, что каждый значок имеет такие свойства, как: идентификатор, имя, класс (бронза, серебро или золото), описание и т. Д.
Вы упоминаете, что в настоящее время у вас есть класс для каждого значка / достижения, каждый с соответствующими проверками на условия, на которых он будет награжден.
Причина, по которой я предлагаю вам отойти от модели, на которую вы сейчас смотрите (один класс на достижение), заключается в том, что вы будете продолжать сталкиваться с огромными проблемами в будущем, когда будете перемещаться по 200 различным классам, ищущим это одно удостоверение личности, которое вы не можете вспомнить.
Храня ваши значки в таблице, ваши данные находятся в одном логическом месте и не разбросаны по вашему приложению.
В ответ на вопрос: Так вы не согласны с принятым ответом на: /questions/3220171/kak-realizovat-znachki
Не обязательно, и мне нравится эта идея больше, чем мое предыдущее предложение об одном классе, который проверял бы все значки на основе их идентификатора.
Несмотря на название, я считаю, что 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); }
}
}
Как насчет использования enum?
public enum BadgeTypes
{
GoodAnswer = 1,
Commenter = 2,
Teacher = 3,
//...
}
Каждый BadgeJob может иметь BadgeType
свойство, которое будет использоваться для заполнения идентификатора значка при вставке достижения во время AwardBadges()
(значения перечисления могут быть сохранены в целые числа).
Я не вижу необходимости иметь один класс на достижение. BadgeJob
содержит всю логику атрибуции и BadgeTypes
Достаточно представить разные значки.