JAVA设计模式-策略模式应用实例

来源:互联网 发布:龙珠直播软件 编辑:程序博客网 时间:2024/05/26 07:28

应用场景:资讯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;    }}
策略工厂

@Componentpublic 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);    }}
调用:

@Resourceprivate StrategyFactory strategyFactory;
Long amount = strategyFactory.creator(req.getChannel()).calculate(param);