stract AbstractMyValidator getNext();
}
由于校验比较多,我们就拿前两个校验作为两个例子,其中添加一个头节点,作为起始节点,后面每一个校验器只需要实现valid校验逻辑,和说明它的下一个校验器是谁即可,最后一个的next就是null。
class HeadValidator extends AbstractMyValidator {
@Override
public AbstractMyValidator getNext() {
return new TaskIdValidator();
}
@Override
public FeedbackUploadCode valid(ValidateContext context) {
return null;
}
}
class TaskIdValidator extends AbstractMyValidator {
@Override
public AbstractMyValidator getNext() {
return new DateFormatValidator();
}
@Override
public FeedbackUploadCode valid(ValidateContext context) {
try {
Long.parseLong(context.getFileBo().getTaskId());
return null;
} catch (NumberFormatException e) {
return FeedbackUploadCode.ERROR_TASK_ID_FORMAT;
}
}
}
class DateFormatValidator extends AbstractMyValidator {
private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DATE_TIME_PATTERN);
@Override
public AbstractMyValidator getNext() {
return null;
}
@Override
public FeedbackUploadCode valid(ValidateContext context) {
try {
LocalDateTime.parse(context.getFileBo().getCollectionTime(), DATE_TIME_FORMATTER);
return null;
} catch (DateTimeParseException e) {
return FeedbackUploadCode.ERROR_DATE_FORMAT;
}
}
}
新增一个Service,对外提供校验方法,核心就是持有校验器的头节点,外部调用只需要组装好上下文,校验方法会通过头节点遍历所有的校验器完成校验。
@Service
public class ValidateService {
@Autowired
private FileDbService fileDbService;
private AbstractMyValidator feedbackValidator = new HeadValidator();
public Boolean valid(ValidateContext context) {
AbstractMyValidator currentValidator = feedbackValidator.getNext();
while (currentValidator != null) {
if (currentValidator.valid(context) != null) {
FeedbackFile file = buildOutsourceFeedbackFile(context.getFileBo(), context.getBatchId(), context.getUser(), context.getFileName());
fileDbService.insert(file);
return false;
}
currentValidator = currentValidator.getNext();
}
return true;
}
private FeedbackFile buildOutsourceFeedbackFile(FileBo fileBo, long batchId, LoginUser user, String fileName) {
FeedbackFile file = new FeedbackFile();
// set value
return file;
}
}
由于校验的规则都比较简单,我们可以把所有的校验器都写到同一个类中,并且代码顺序就是校验的顺序,当然也可以像sentinel一样维护一个顺序值,或者像spring拦截器一样把它们按照顺序添加到集合中。
这样以后新增一个校验规则,就只需要新增一个校验器,并且把它放到链表合适的位置即可,真正做到对扩展开放,对修改封闭。
更多分享,欢迎关注我的github:https://github.com/jmilktea/jtea