策略模式&模版模式 简单运用
策略模式简单运用
背景是 根据不同的渠道,处理不同的任务,相比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,"");
}
}
}
}
elk