策略模式&模版模式 简单运用

策略模式简单运用

背景是 根据不同的渠道,处理不同的任务,相比if else 可以不用动主逻辑代码,代码可维护性好点,每次处理不同渠道的任务只需要改对应的实现,缺点就是的增加类的数量,核心就是多态。

1. 定义接口
public interface TaskFileHandleService {

    /**
     * 获取任务类型
     * @return
     */
    TaskTypeEnum getTaskType();

    /**
     * 任务文件处理
     * @param task
     */
    void taskFileHandle(Task task);

}

2. 定义宏观类

注入 所有接口实现类,循环匹配即可。

@Service
public class TaskFileHandleStrategy {

    @Autowired
    private List<TaskFileHandleService> taskFileHandleServiceList;

    /**
     * 处理逻辑
     * @param task
     */
    public void handle(Task task){
        for (int i = 0; i < taskFileHandleServiceList.size(); i++) {
            TaskFileHandleService taskFileHandleService = taskFileHandleServiceList.get(i);
            TaskTypeEnum taskType = taskFileHandleService.getTaskType();
            if(Objects.equals(TaskTypeEnum.of(task.getTaskType()),taskType)){
                taskFileHandleService.taskFileHandle(task);
            }
        }
    }
}

3.使用

注入对应的类 taskFileHandleStrategy.handle(task) 即可,主逻辑不用动,每次新加任务,加一个具体实现类即可,也就是所谓面向 接口编程的灵活性。

  @Autowired
  private TaskFileHandleStrategy taskFileHandleStrategy;

  
  @Override
  public void handleTaskJob(List<Task> taskList) {
        if(CollectionUtil.isNotEmpty(taskList)){
            // 根据任务类型解析文件
            taskList.stream().forEach(task -> {
                // 导出任务 线程池 处理
                if(Objects.equals(TaskTypeEnum.DOWNLOAD_AIRCRAFT_CHEF.getValue(),task.getTaskType())){
                    executor.execute(() ->{
                        doTask(task);
                    });
                }else {
                    doTask(task);
                }
            });
        }
    }


 /**
     * 做任务
     * @param task
     */
    private void doTask(Task task){
        try {
            handleTask(task);
        }catch (Exception e){
            log.error("处理任务失败 任务id={} 任务名称={} 任务信息",task.getId(),task.getName(),e);
            task.setFailReason(ExceptionUtil.stacktraceToOneLineString(e,Constants.EXCEPTION_MSG_SIZE));
            handleFailed(task);
        }
    }

   /**
     * 处理任务
     * @param task
     */
    private void handleTask(Task task) {
        Task newTask = new Task();
        newTask.setId(task.getId());
        newTask.setStatus(TaskStatusEnum.PROCESSING.getValue());
        newTask.setStartTime(LocalDateTime.now());
        updateById(newTask);
        taskFileHandleStrategy.handle(task);
        handleSuccess(task);
    }

再次抽取 公共,定义抽象类 也就是模版模式

@Slf4j
public abstract class AdminAbstractTaskFileHandleService implements AdminTaskFileHandleService {

    @Autowired
    private AliOssService aliOssService;

    @Lazy
    @Autowired
    private AdminTaskService adminTaskService;

    public void taskHandle(Task task) {
        //创建目录文件地址
        String realFileName = createFile(task);
        // 执行业务逻辑
        this.taskFileHandle(task,realFileName);
        // 上传文件
        upFile(task,realFileName);
    }


    private String createFile(Task task) {
        String downloadDefaultDir = Constants.DOWNLOAD_DEFAULT_DIR;
        File file = new File(downloadDefaultDir);
        if (!file.exists()) {
            file.mkdirs();
        }

        String realFileName = downloadDefaultDir + task.getName() + StringPool.XLSX;
        // 存在先删除文件
        File oldFile = new File(realFileName);
        if (oldFile.exists()) {
            oldFile.delete();
        }
        return realFileName;
    }

    private void upFile(Task task,String realFileName) {
        String fileName = task.getName() + StringPool.XLSX;
        //上传文件写入文件url
        File oldFile = new File(realFileName);
        try {
            FileInputStream fileInputStream = new FileInputStream(realFileName);
            UpInputStream upInputStream = new UpInputStream();
            upInputStream.setInputStream(fileInputStream);
            upInputStream.setFileName(fileName);
            KbFile kbFile = aliOssService.putFileCover(upInputStream);
            Task newTask = new Task();
            newTask.setId(task.getId());
            newTask.setTaskFile(kbFile.getLink());
            adminTaskService.updateById(newTask);
        } catch (FileNotFoundException e) {
            log.error("文件流不存在");
        }
        // 删临时文件
        if (oldFile.exists()) {
            oldFile.delete();
        }
    }

}

修改策略方法 调用抽象类,原来实现接口 改为 extends AdminAbstractTaskFileHandleService

@Service
public class TaskFileHandleStrategy {

    @Autowired
    private List<AdminAbstractTaskFileHandleService> taskFileHandleServiceList;

    /**
     * 处理逻辑
     * @param task
     */
    public void handle(Task task){
        for (int i = 0; i < taskFileHandleServiceList.size(); i++) {
            AdminAbstractTaskFileHandleService taskFileHandleService = taskFileHandleServiceList.get(i);
            TaskTypeEnum taskType = taskFileHandleService.getTaskType();
            TaskTypeEnum taskTypeEnum = TaskTypeEnum.of(task.getTaskType());
            if(Objects.equals(taskTypeEnum.getValue(),taskType.getValue()) && taskTypeEnum.getIsExport()){
                taskFileHandleService.taskHandle(task);
            }
            if(Objects.equals(taskTypeEnum.getValue(),taskType) && !taskTypeEnum.getIsExport()){
                taskFileHandleService.taskFileHandle(task,"");
            }
        }
    }
}
posted @ 2024-05-02 14:16  川流不息&  阅读(67)  评论(0编辑  收藏  举报