2012-12-18 8 views
5

Istnieje już wiele pytań dotyczących kodowania systemu znaczków podobnego do SO, moje pytanie jest inne. Załóżmy, że mam system stron WWW, odznaki/osiągnięcia, przechowywane w DB jako wiersz z kluczem osiągnięcia (identyfikator), identyfikatorem użytkownika i innymi danymi.Architektura osiągnięć/odznak

Moje proste pytanie brzmi: gdzie powinienem przechowywać identyfikator identyfikatora? Mam jedną klasę na osiągnięcie, wszystkie dane i metody testowania, jeśli zostały uzyskane. Wyobrażam sobie, że w pewnym momencie mogę mieć dziesiątki lub setki. Chcę, aby identyfikatory były używane tylko raz i w jednym zwięzłym miejscu, więc nie mam szans na ich przypadkową zmianę lub zmieszanie.

mogę ciężko zakodować je w klasie, jak

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

ale jeśli podzielić moje osiągnięcia wśród wielu plików nie chcę mieć biegać szukasz najwyższej Key kiedy dodać nowy jeden i ryzykować pomyłkę.

mogę umieścić je w jakimś słowniku w innej klasy ...

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

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

Ale teraz sama klasa nie zna swój własny klucz, a to wymaga (lub nie?) Gdybym przeszedł teraz do konstruktora ryzykuję niedopasowanie liczb.

Jakieś rekomendacje?

+1

Dlaczego nie przechowujesz odznak w bazie danych? –

+1

Przypuszczam, ponieważ kod jest związany z każdą odznaką i nadal trzeba dopasować ten fragment kodu z identyfikatorem identyfikatora. Więc w zasadzie nic nie rozwiąże. – guillaume31

Odpowiedz

2

W kontekście przepełnienie stosu, to bym sobie wyobrazić każdy odznaki ma właściwości takie jak: id, nazwisko, klasa (brąz, srebro lub złoto) oraz opis itd

można wspomnieć, że obecnie mają klasa dla każdej odznaki/osiągnięcia, każda z odpowiednimi kontrolami dla warunków, na których zostanie przyznana.

Powodem, dla którego sugeruję, abyś odsunął się od modelu, na który teraz patrzysz (jedna klasa na osiągnięcie), jest to, że podczas podróży przez cały czas będziesz musiał zmierzyć się z ogromnymi problemami. różne klasy szukające tego jednego identyfikatora, którego nie pamiętasz.

Dzięki przechowywaniu odznak w tabeli wszystkie dane znajdują się w jednym logicznym miejscu i nie są rozproszone we wszystkich aplikacjach.

W odpowiedzi na pytanie: Więc nie zgadzasz się z przyjętą odpowiedzi: stackoverflow.com/questions/3162446/

niekoniecznie, a ja lubię ten pomysł bardziej niż moim wcześniejszym wnioskiem o jedną klasę, która będzie sprawdzić wszystkie odznaczenia w oparciu o ich identyfikator.

Mimo swojej nazwy, uważam, że RexM nie definiuje samego siebie w tym pliku jako CommenterBadge i powinien go nazwać CommenterBadgeJob. (Zauważysz, że nie ma żadnej z cech, które zdefiniowałem w mojej odpowiedzi i dziedziczy po BadgeJob). Oczywiste pytanie brzmi: "W jaki sposób każda praca odznak rozpoznaje, której BadgeId odpowiada?"

Będę mieć dodatkowe unikatowe pole w moim Badge o nazwie BadgeJob, dzięki któremu można wyszukać znaczek.

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

chciałbym zmodyfikować swój kod w następujący sposób:

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

Więc nie zgadzasz się z zaakceptowaną odpowiedzią na http://stackoverflow.com/questions/3162446/how-to-implement-badges?rq=1? – Tesserex

+0

Zaktualizowałem moją odpowiedź. Gdybym był niejasny, daj mi znać, a ja spróbuję jeszcze raz poprawić moją odpowiedź. – JoshVarty

+0

Poszedłem z umieszczaniem wszystkich danych w bazie danych, która działa dobrze, ponieważ większość moich osiągnięć będzie miała proste warunki, takie jak pewne pole> = próg. Dzięki! – Tesserex

2

Jak o użyciu enum?

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

Każdy BadgeJob może mieć BadgeType nieruchomości, które będą używane do zapełniania identyfikator odznakę podczas wstawiania osiągnięcie podczas AwardBadges() (wartości enum można utrzymywały się do liczb całkowitych).

Nie widzę potrzeby posiadania jednej klasy na osiągnięcie. BadgeJob zawiera logikę atrybucji znaczków i BadgeTypes wystarczającą do reprezentowania różnych znaczków.

+0

Ale czy nie ma jednej klasy "Job" na osiągnięcie? To wygląda tak samo ... Nie chcę jednej klasy "Logic", która ma tysiące linii. – Tesserex

+0

Tak, jest jedna klasa pracy na osiągnięcie ("BadgeJob ** 's zawiera ** ..."). Przepraszam, jeśli to nie było jasne. – guillaume31

+0

Czy masz na myśli, że nie chcesz jednej klasy zawodowej na osiągnięcie? Nie widzę, jak to będzie krótsze:/ – guillaume31