JAVA設計模式-策略模式應用實例

應用場景:資訊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);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章