Архитектура для достижений / значков

Уже много вопросов о кодировании системы бейджей, аналогичной 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 Достаточно представить разные значки.

Другие вопросы по тегам