2010-05-28 6 views
2

Ceci est une question de conception mieux expliquée par une analogie Stack Overflow:objets Stratégie Gestion avec Hibernate et Spring

Les utilisateurs peuvent gagner des badges. Les utilisateurs, les badges et les badges acquis sont stockés dans la base de données. La logique d'un badge est exécutée par une stratégie de condition de badge. Je préférerais ne pas avoir à stocker des stratégies de condition de badge dans la base de données, car ce sont des objets de structure arborescente complexes. Comment associer un badge stocké dans la base de données à sa stratégie de condition de badge? Je ne peux penser qu'à des solutions de contournement. Par exemple: créez 1 classe par badge et utilisez une stratégie d'héritage SINGLE_TABLE. Ou récupérez le badge de la base de données, puis recherchez par programme et injectez la stratégie de condition de badge correcte.

Merci d'avoir suggéré un meilleur design.

+0

Question intéressante (+1) –

Répondre

1

Je ne vois pas pourquoi vous devriez stocker une stratégie en DB - stratégie est principalement exprimée en code (éventuellement avec certains paramètres de configuration qui, à leur tour, peuvent être stockés dans DB, mais c'est un problème différent pour moi) .

OTOH Je garderais le Badge et sa stratégie de condition dans une classe, ce qui élimine votre problème de recherche. En Java, un bon modèle de domaine serait de représenter les badges comme une énumération, avec une méthode redéfinie pour déterminer si un utilisateur donné a gagné ce badge spécifique.

Mise à jour est ici un exemple:

enum Badge { 
    EPIC() { 
    public boolean isEligible(User user) { 
     // determine whether this user is eligible for the Epic badge 
    } 
    }, 
    CRITIC() { 
    public boolean isEligible(User user) { 
     // determine whether this user is eligible for the Critic badge 
    } 
    }, 
    ... 
    ; 

    public abstract boolean isEligible(User user); 
} 

Mais si vous voulez vraiment les séparer, puis dans le constructeur de par exemple vous dites this.strategy = new LegendaryBadgeConditionStrategy();

+0

Merci Peter. Je ne veux pas stocker la stratégie dans DB. Je fais ce que vous suggérez, mais je ne vois toujours pas comment un insigne va être associé à sa condition d'insigne sans piratage. Imaginez que le Badge possède un champ privé BadgeCondition défini par constructeur ou setter, mais que BadgeCondition est transitoire. – Francois

+0

@Francois, voir ma mise à jour. –

+0

@Francois, une note supplémentaire: l'utilisation d'une stratégie distincte de l'insigne n'aurait de sens pour moi que si les stratégies pour un badge spécifique pourraient varier en fonction de facteurs externes ou internes. Pour les badges, ce n'est pas le cas - les conditions pour obtenir un badge spécifique sont les mêmes pour tous les utilisateurs à un moment donné. Ils peuvent changer au fil du temps, mais assez rarement, ce qui ne me justifie pas pleinement d'utiliser le schéma de la Stratégie ici. –

1

Que diriez-vous d'un BadgeType enum avec des types qui correspondent aux badges dans la base de données? Le ENUM peut avoir une méthode getBadgeConditionStrategy() qui retourne la bonne stratégie pour chaque valeur ENUM:

public enum BadgeType { 
    SMARTNESS(new SmartnessBadgeConditionStrategy()), 
    WISDOM(new WisdomBadgeConditionStrategy(), 
    ...; 

    private BadgeConditionStrategy badgeConditionStrategy; 
    BadgeType(BadgeConditionStrategy badgeConditionStrategy) { 
      this.badgeConditionStrategy = badgeConditionStrategy; 
    } 

    public getBadgeConditionStrategy() { 
     return badgeConditionStrategy; 
    } 
} 
Questions connexes