应用场景:资讯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);