應用場景:資訊app對用戶的有益反饋、首次評論、分享、版本更新等發放積分,積分系統分別設置有益反饋、首次評論、分享、版本更新的積分規則,根據不同的積分規則取出要送的積分。
基礎策略接口
public interface BaseStrategy { /** * 根據規則計算積分 * * @param param * @return */ Long calculate(StrategyParam param); /** * 類型 * * @return */ ISChannelType getFlag(); }抽象類,實現通用計算積分方法,特殊的子類重寫計算積分方法即可
public abstract class IntegralAbstractStrategy implements BaseStrategy{ @Resource ISAccountDetailMapper iSAccountDetailMapper; /** * 簡單獲取 積分 * @param param * @return */ @Override public Long calculate(StrategyParam param) { RuleData ruleData = param.getRule().get(RuleKeys.FEEDBACK); if (ruleData!=null){ return Long.valueOf(StringUtil.isBlank(ruleData.getValue())?"0":ruleData.getValue()); } return 0L; } }有益分享實現
@Component("feedbackStrategy") public class FeedbackStrategy extends IntegralAbstractStrategy { @Override public ISChannelType getFlag() { return ISChannelType.FEEDBACK; } }首次評論實現
@Component("firstCommentStrategy") public class FirstCommentStrategy extends IntegralAbstractStrategy { @Override public Long calculate(StrategyParam param) { String userId = param.getUserId(); Map<String, RuleData> rule = param.getRule(); if (rule.containsKey(RuleKeys.FIRST_COMMENT)) { RuleData ruleData = rule.get(RuleKeys.FIRST_COMMENT); String value = ruleData.getValue(); if (StringUtil.isNotBlank(value)) { //首次評論防止重複,增加校驗 ISAccountDetailExample example = new ISAccountDetailExample(); ISAccountDetailExample.Criteria criteria = example.createCriteria(); criteria.andUserIdEqualTo(userId); criteria.andChannelEqualTo(ISChannelType.FIRST_COMMENT.getCode()); List<ISAccountDetail> isAccountDetails = iSAccountDetailMapper.selectByExample(example); if (CollectionUtils.isEmpty(isAccountDetails)) { Long amount = Long.valueOf(value); return amount; } } } return 0L; } @Override public ISChannelType getFlag() { return ISChannelType.FIRST_COMMENT; } }積分渠道枚舉
public enum ISChannelType implements BaseEnum { //新用戶 NEW_REGISTER(0, "NEW_REGISTER", "新用戶註冊"), FIRST_COMMENT(0, "FIRST_COMMENT", "首次評論"), FIRST_SHARE(0, "FIRST_SHARE", "首次分享"), //常規 DRAW(1, "DRAW", "抽獎"), READ_RED(1, "READ_RED", "閱讀紅包"), COMMENT(1, "COMMENT", "用戶評論"), SHARE(1, "SHARE", "文章分享"), INVITE(1, "INVITE", "邀請好友"), FEEDBACK(1, "FEEDBACK", "有益反饋"), UPDATE_VERSION(1, "UPDATE_VERSION", "APP版本更新"), JIFEN_CONVERT(1, "JIFEN_CONVERT", "積分兌換金額"), JIFEN_CONVERT_DRAW(1, "JIFEN_CONVERT_DRAW", "積分兌換抽獎次數"), JIFEN_VALID(1, "JIFEN_VALID", "積分有效期"),; /** * 類型,0爲新用戶專有,1爲常規 */ private int type; private String code; private String desc; ISChannelType(int type, String code, String desc) { this.type = type; this.code = code; this.desc = desc; } /** * 獲取所有渠道code * * @return */ public static List<String> getCodes() { List<String> codes = Lists.newArrayList(); ISChannelType[] values = ISChannelType.values(); for (ISChannelType value : values) { codes.add(value.getCode()); } return codes; } /** * 獲取枚舉代碼 */ @Override public String getCode() { return code; } /** * 獲取枚舉描述 */ @Override public String getDesc() { return desc; } /** * Getter method for property <tt>type</tt> * * @return property value of type */ public int getType() { return type; } }策略工廠
@Component public class StrategyFactory extends ApplicationObjectSupport { private transient Logger log = LoggerFactory.getLogger(getClass()); private static Map<String, BaseStrategy> strategyMap = new HashMap<>(); @PostConstruct private void init() { Map<String, BaseStrategy> beansOfType = getApplicationContext().getBeansOfType(BaseStrategy.class); beansOfType.values().forEach(it -> strategyMap.put(it.getFlag().getCode(), it)); log.info("Registered strategy size: {}", strategyMap.size()); } public BaseStrategy creator(String type) { return strategyMap.get(type); } }調用:
@Resource private StrategyFactory strategyFactory;
Long amount = strategyFactory.creator(req.getChannel()).calculate(param);