5

SO に似たバッジ システムのコーディングについては、すでに多くの質問がありますが、私の質問は異なります。アチーブメント キー (id)、ユーザー ID、およびその他のデータを含む行として DB に格納されている Web ページ システム、バッジ/アチーブメントがあるとします。

私の簡単な質問は、バッジ ID をどこに保存すればよいですか? 達成されたかどうかをテストするためのすべてのデータとメソッドを含む、達成ごとに 1 つのクラスがあります。ある時点で数十または数百になると思います。ID を 1 回だけハード コードして、1 つの簡潔な場所で使用するようにしたいので、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

スタック オーバーフローのコンテキストでは、各バッジには ID、名前、クラス (ブロンズ、シルバー、ゴールド)、説明などのプロパティがあると思います。

あなたは現在、バッジ/実績ごとにクラスがあり、それぞれが授与される条件について適切なチェックを行っていると述べています。

現在見ているモデル (実績ごとに 1 つのクラス) から離れることをお勧めする理由は、今後も 200 の異なるクラスをナビゲートする際に大きな問題に直面し続けることになるためです。あなたが思い出せないその1つのID。

バッジをテーブルに保存することにより、データはすべて 1 つの論理的な場所にあり、アプリケーション全体に散らばることはありません。

質問への回答: 受け入れられた回答に同意しませんか: 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

enum を使用するのはどうですか?

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

各 BadgeJob にはBadgeType、アチーブメントを挿入するときにバッジ ID を設定するために使用されるプロパティがありますAwardBadges()(列挙値は整数に保持できます)。

アチーブメントごとに 1 つのクラスを持つ必要はないと思います。BadgeJobにはすべてのバッジ属性ロジックが含まれておりBadgeTypes、さまざまなバッジを表すのに十分です。

于 2012-12-18T13:22:18.583 に答える