开发者

Managing Strategy objects with Hibernate & Spring

开发者 https://www.devze.com 2023-01-01 04:40 出处:网络
This is a design question better explained with a Stack Overflow analogy: Users can earn Badges. Users, Badges and Earned Badges are stored in the database. A Badge’s logic is run by a Badge Conditi

This is a design question better explained with a Stack Overflow analogy:

Users can earn Badges. Users, Badges and Earned Badges are stored in the database. A Badge’s logic is run by a Badge Condition Strategy. I would prefer not to have to store Badge Condition Strategies in the database, because they are complex tree structure objects.

How do I associate a Badge stored in the database with its Badge Condition Strategy? I can only think of workaround solutions. For example: create 1 class per badge and use a SINGLE_TABLE inheritance strategy开发者_运维知识库. Or get the badge from the database, and then programmatically lookup and inject the correct Badge Condition Strategy.

Thanks for suggesting a better design.


I don't see why you should store a strategy in DB - strategy is mostly expressed in code (possibly with some configuration parameters which, in turn, can be stored in DB, but that is a different issue to me).

OTOH I would keep the Badge and its condition strategy in one class, which eliminates your lookup problem. In Java, a good domain model would be to represent badges as an enum, with an overridable method to determine whether a given user has earned that specific badge.

Update here is an example:

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

But if you really want them separated, then in the constructor of e.g. LegendaryBadge you say this.strategy = new LegendaryBadgeConditionStrategy();


How about a BadgeType enum with types that correspond to the Badges in the database? The enum can have a getBadgeConditionStrategy() method that returns the correct strategy for each enum value:

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

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

     public getBadgeConditionStrategy() {
         return badgeConditionStrategy;
     }
 }
0

精彩评论

暂无评论...
验证码 换一张
取 消