Управление стратегическими объектами с помощью Hibernate & Spring


Этот вопрос проектирования лучше объяснить с помощью аналогии переполнения стека:

Пользователи могут зарабатывать значки. Пользователи, значки и заработанные значки хранятся в базе данных. Логика значка управляется стратегией условий значка. Я бы предпочел не хранить стратегии состояния значка в базе данных, потому что они являются сложными объектами древовидной структуры.

Как связать значок, хранящийся в базе данных, с его стратегией состояния значка? Я могу думать только о обходных решениях. Например: создайте 1 класс на значок и используйте стратегию наследования SINGLE_TABLE. Или получить значок из базы данных, а затем программно искать и вводить правильную стратегию состояния значка.

Спасибо, что предложили лучший дизайн.

2 2

2 ответа:

Я не вижу, почему вы должны хранить стратегию в БД-стратегия в основном выражается в коде (возможно, с некоторыми параметрами конфигурации, которые, в свою очередь, могут храниться в БД, но это другой вопрос для меня).

OTOH я бы сохранил значок и его стратегию состояния в одном классе,что устраняет проблему поиска. В Java хорошей моделью домена было бы представление значков в виде перечисления с переопределяемым методом, чтобы определить, заработал ли данный пользователь этот конкретный значок.

Обновление Вот пример:

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

Но если вы действительно хотите, чтобы они были разделены, то в конструкторе, например LegendaryBadge Вы говорите this.strategy = new LegendaryBadgeConditionStrategy();

Как насчет перечисления BadgeType с типами, которые соответствуют значкам в базе данных? Перечисление может иметь метод getBadgeConditionStrategy (), который возвращает правильную стратегию для каждого значения перечисления:

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

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

     public getBadgeConditionStrategy() {
         return badgeConditionStrategy;
     }
 }