背景: 设计一个任务系统, 任务可以有多种类型(签到,看广告,填写调查问卷 等等),每个任务的完成标准是 可以做N次。 需要记录每个任务的完成进度。每做一次需要做一些操作,如 给用户增减积分等。

设计:抽象类

@Slf4j
public abstract class AbstractTaskPostProcessor {

     // 由子类实现。
    abstract Boolean beforeProcess(UserTaskDTO userTask);
    // 由子类实现。
    abstract Boolean process(UserTaskDTO userTask);
    // 由子类实现。
    abstract Boolean afterProcess(UserTaskDTO userTask);

    /**
     * 上报任务后,统一的处理计算过程。
     **/
    public ActivityPlayerTaskVO calculate(UserTaskDTO userTask){
       
        // 确认唯一标识符
        String uid = "用户的唯一标识符";
        log.info("开始任务计算,openId={}",openId);
        RLock lock = redissonService.getRLock("task_calculate_" + activityId + uid);
        try {
            boolean bs = lock.tryLock();
            if (!bs) {
                log.info("任务计算中,请稍后再试");
                throw new BusinessException("任务计算中,请稍后再试");
            }

              // 处理前的特殊处理。              
               beforeProcess(userTask);

             // xxxxxx共性的操作

            // 业务特殊处理
            Boolean result = process(userTask);
            log.info("任务的处理结果:{}",result);
            // 处理成功更新次数
            if (result) {
                  // 处理成功的特殊处理。              
                  afterProcess(userTask);
        }catch (Exception ex){
            log.error("任务处理失败,原因:{}",ex);
            throw ex;
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return playerTaskVO;
    }

 

根据业务类型,取子类的对象

public enum TaskActionEnum {
    TASK_SIGN_IN(1, "签到"),
    TASK_LOOK_AD(2,"看广告")
}

public class PostProcessorFactory {

    public static AbstractTaskPostProcessor getPostProcessor(TaskActionEnum action) {
        switch (action){
            case TASK_SIGN_IN: // 签到
                return SpringContextUtil.getBean(TaskSignInProcessor.class);
            case TASK_LOOK_AD: // 看广告
                return SpringContextUtil.getBean(TaskLookAdProcessor.class);
            default:
                throw new BusinessException(GameErrorCodeEnum.ERROR_FORMAT);
        }
    }
}

  子类的实现:

@Service
public class TaskSignInProcessor extends AbstractTaskPostProcessor{

    @Autowired
    private IBaishiSignRecordService signRecordService;

    @Override
    public Boolean beforeProcess(UserTaskDTO userTask) {
        return Boolean.TRUE;
    }

    @Override
    public Boolean process(UserTaskDTO userTask) {
        return Boolean.TRUE;
    }

    @Override
    public Boolean afterProcess(UserTaskDTO userTask) {
        return Boolean.TRUE;
    }
}

 

调用的入口:

    public ApiResult report(UserTaskDTO userTask){
        ActivityPlayerTaskVO playerTask = PostProcessorFactory.getPostProcessor(userTask.getAction()).calculate(userTask);
        return ApiResult.success(playerTask);
    }

 

posted on 2023-02-23 14:17  毛会懂  阅读(33)  评论(0编辑  收藏  举报