2012-12-18 27 views
5

Es gibt schon viele Fragen zum Kodieren eines Ausweises ähnlich wie SO, meine Frage ist anders. Angenommen, ich habe ein Webseitensystem, Abzeichen/Erfolge, die in der Datenbank als Zeile mit dem Leistungsschlüssel (ID), der Benutzerkennung und anderen Daten gespeichert sind.Architektur für Erfolge/Abzeichen

Meine einfache Frage ist, wo soll ich die Badge ID speichern? Ich habe eine Klasse pro Leistung mit allen Daten und Methoden zum Testen, wenn es verdient wurde. Ich kann mir vorstellen, dass ich irgendwann Dutzende oder Hunderte habe. Ich möchte, dass die IDs nur einmal und an einem bestimmten Punkt fest codiert sind, so dass ich keine Chance habe, sie versehentlich zu ändern oder zu vermischen.

ich schwer, sie in der Klasse codieren könnte, wie

public int Key { get { return 15; } } // I'm calling it Key, not ID 

aber wenn ich mehrere Dateien meine Leistungen unter geteilt Ich will nicht um den höchsten Schlüssel suchen zu laufen haben, wenn ich eine neue hinzufügen man und riskiere einen Fehler.

ich sie in irgendeinem Wörterbuch in einer anderen Klasse setzen könnte ...

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

    public AchievementSet() 
    { 
     _achievements = new Dictionary<int, Achievement>() 
     { 
      { 1, new SomethingAchievement() } 
     }; 
    } 
} 

Aber jetzt ist die Klasse selbst nicht weiß, seinen eigenen Schlüssel, und es muss (oder doch?) Wenn ich bestehen es in den Konstrukteur jetzt riskiere ich die Zahlen nicht übereinstimmen.

Irgendwelche Empfehlungen?

+1

Warum würden Sie die Badges nicht in der Datenbank speichern? –

+1

Ich nehme an, weil jedem Code ein Code zugeordnet ist und Sie diesen Code immer noch mit der Badge-ID abgleichen müssen. Es würde also grundsätzlich nichts lösen. – guillaume31

Antwort

2

Im Zusammenhang mit dem Stack-Überlauf, ich jedes Abzeichen vorstellt haben Eigenschaften, wie zum Beispiel: ID, Name, Klasse (Bronze, Silber oder Gold) und Beschreibung usw.

Sie erwähnen, dass Sie zur Zeit eine haben Klasse für jedes Abzeichen/Leistung, jeweils mit entsprechenden Prüfungen für die Bedingungen, zu denen es vergeben würde.

Der Grund, warum ich vorschlage, dass Sie sich von dem Modell wegbewegen, das Sie gerade betrachten (eine Klasse pro Errungenschaft), liegt daran, dass Sie beim Navigieren durch 200 weiterhin große Probleme haben werden verschiedene Klassen, die nach dieser einen ID suchen, an die Sie sich nicht erinnern können.

Wenn Sie Ihre Badges in der Tabelle speichern, sind Ihre Daten an einem logischen Ort und nicht über Ihre Anwendung verstreut.

In Antwort auf die Frage: Also tun Sie nicht einverstanden mit der akzeptierten Antwort an: stackoverflow.com/questions/3162446/

Nicht unbedingt, und Ich mag diese Idee mehr als mein früherer Vorschlag für eine einzige Klasse, die all Abzeichen überprüfen würde, basierend auf ihre ID.

Trotz seines Namens glaube ich, dass RexM nicht die CommenterBadge selbst in dieser Datei definiert und sollte es CommenterBadgeJob benannt haben. (Sie werden bemerken, dass es keine der Merkmale hat, die ich in meiner Antwort definiert habe und erbt von BadgeJob). Die offensichtliche Frage ist: "Wie weiß jeder Abzeichenjob, welcher BadgeId er entspricht?"

Ich hätte ein zusätzliches eindeutiges Feld in meinem Badge genannt BadgeJob, mit dem Sie ein Abzeichen nachschlagen könnten.

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} 
} 

Ich würde seinen Code wie folgt ändern:

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); } 
    } 
} 
+0

Also stimmen Sie nicht mit der akzeptierten Antwort auf http://stackoverflow.com/questions/3162446/how-to-implement-badges?rq=1 überein? – Tesserex

+0

Ich habe meine Antwort aktualisiert. Wenn ich unklar war, lass es mich wissen und ich werde versuchen, meine Antwort noch einmal zu überarbeiten. – JoshVarty

+0

Ich habe alle Daten in eine Datenbank eingegeben, was gut funktioniert, da die meisten meiner Leistungen einfache Bedingungen haben werden, wie zum Beispiel ein Feld> = Schwelle. Vielen Dank! – Tesserex

2

Wie wäre es eine ENUM verwenden?

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

Jede BadgeJob könnte eine BadgeType Eigenschaft hat, die das Abzeichen ID aufzufüllen verwendet werden würde, wenn sie während AwardBadges() (ENUM-Werte auf ganze Zahlen beibehalten werden können) einen Erfolg einsetzen.

Ich sehe keine Notwendigkeit für eine Klasse pro Leistung. BadgeJob 's enthalten alle Abzeichen Attributionslogik und BadgeTypes ausreichen, um die verschiedenen Abzeichen darzustellen.

+0

Aber gibt es nicht eine 'Job' Klasse pro Errungenschaft? Das scheint dasselbe zu sein ... Ich will keine "Logik" -Klasse, die tausende Zeilen lang ist. – Tesserex

+0

Ja, es gibt eine Jobklasse pro Errungenschaft ("BadgeJob ** 's enthält ..." war Plural). Tut mir leid, wenn das nicht klar war. – guillaume31

+0

Oder meinen Sie, Sie wollen keine Jobklasse pro Leistung? Ich sehe nicht, wie das kürzer wäre:/ – guillaume31