模板模式 + 策略模式


本篇主要记录和总结工作中用到模板 + 策略 + 工厂模式的一种实现方式

先抽象公共的方法模板

/**
 * @author feiliang
 * @date 2022/4/20 21:56
 */
public abstract class AbstractService {
    @Resource
    private LevelFactory levelFactory;

    /**
     * 处理流程模板
     */
    protected String handle() {
        // 1. 获取需要处理的数据
        String data = this.getData();
        // 2. 获取对象
        Consumer consumer = this.getConsumer(data);
        // 3. 获取等级策略处理
        ILevelHandle levelHandler = levelFactory.get(consumer.getLevelCode());
        // 4. 等级改变处理
        String changeType = this.getChangeType();
        boolean change = levelHandler.handle(consumer, changeType);
        // 5. 记录用户等级变化DB操作
        return null;
    }

    /**
     * 获取需要处理的数据
     */
    protected abstract String getData();

    /**
     * 获取等级和金额
     *
     * @param consumerCode
     * @return
     */
    protected abstract Consumer getConsumer(String consumerCode);

    /**
     * 获取升级或者降级类型 LevelChangeTypeConstants
     *
     * @return
     */
    protected abstract String getChangeType();

    /**
     * 1升级、2降级、3续会
     *
     * @return
     */
    protected abstract int getLevelChangeType();
}

定义接口

/**
 * @author feiliang
 * @date 2022/4/20 13:53
 */
public interface ILevelService {
    /**
     * 等级变动计算
     * @return
     */
    String changeLevel();
}

接口实现

/**
 * @author feiliang
 * @date 2022/4/20 13:56
 */
@Slf4j
@Service
public class UpgradeLevelServiceImpl extends AbstractLevelService implements ILevelService {

    @Override
    public String changeLevel(String changeType) {
        return super.handle();
    }

    @Override
    protected List<String> getData() {
        return "aaa";
    }

    @Override
    protected ConsumerMember getConsumer(String consumerCode) {
        // DB操作
        return null;
    }

    @Override
    protected String getChangeType() {
        // 枚举返回值
        return null;
    }
}

定义策略接口

/**
 * @author feiliang
 * @date 2022/4/20 17:39
 */
public interface ILevelHandle {

    /**
     * 升级
     *
     * @param consumer
     * @param amount
     * @return 是否有变更等级
     */
    Boolean upgrade(Consumer consumer, BigDecimal amount);

    /**
     * 降级
     *
     * @param consumer
     * @param amount
     * @return 是否有变更等级
     */
    Boolean demotion(Consumer consumer, BigDecimal amount);

    /**
     * 变动等级
     *
     * @param consumer
     * @param changeType
     * @param amount
     * @return 是否有变更等级
     */
    default Boolean handle(Consumer consumer, String changeType, BigDecimal amount) {
        valid(consumer, changeType, amount);
        return changeLevel(consumerMember, changeType, amount);
    }

    /**
     * 内部校验
     *
     * @param consumer
     * @param changeType
     * @param amount
     */
    default void valid(Consumer consumer, String changeType, BigDecimal amount) {
        Assert.notNull(consumer, "consumer object can not be null");
        Assert.notNull(amount, "amount object can not be null");
        Assert.isTrue(StringUtil.isNotBlank(changeType), "changeType can not be null");
        Assert.isTrue(Sets.newHashSet(LevelChangeTypeConstants.UPGRADE, LevelChangeTypeConstants.DEMOTION).contains(changeType),
                "changeType is error");
    }

    /**
     * 改变等级
     *
     * @param consumer
     * @param changeType
     * @param amount
     * @return 是否有变更等级
     */
    default Boolean changeLevel(Consumer consumer, String changeType, BigDecimal amount) {
        if (LevelChangeTypeConstants.UPGRADE.equals(changeType)) {
            return upgrade(consumer, amount);
        } else if (LevelChangeTypeConstants.DEMOTION.equals(changeType)) {
            return demotion(consumer, amount);
        }
        return false;
    }

    /**
     * expire_time设置为当前日期+12个月的日期时间
     *
     * @return 新的失效时间
     */
    default LocalDateTime updateExpireTime() {
        return DateUtil.fromDate(new Date()).plusYears(1);
    }
}

策略接口实现

@Service(LevelChangeTypeConstants.BRONZE_MEDAL)
public class BronzeMedalLevelHandle implements ILevelHandle {

    @Override
    public Boolean upgrade(Consumer consumer, BigDecimal memberLevelTotalAmount) {
        // 升级逻辑
        return true;
    }

    @Override
    public Boolean demotion(Consumer consumer, BigDecimal memberLevelTotalAmount) {
        // 降级逻辑
        return true;
    }
}

策略工厂

/**
 * @author feiliang
 * @date 2022/4/20 17:47
 */
@Component
public class LevelFactory {
    @Lazy
    @Resource
    private Map<String, ILevelService> levelHandleMap;

    /**
     * 根据类型获取对应策略
     *
     * @param levelCode 等级类型
     * @return
     */
    public IMemberLevelService get(String levelCode) {
        return levelHandleMap.get(levelCode);
    }
}

总结

本案例主要结合策略,工厂,模板模式解决公共流程的处理,本案例由于复杂业务导致策略模式较为复杂,平时中直接正常策略即可。


文章作者: Adbo
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Adbo !
评论
  目录