我们先来看一个数据库表结构
这个库是记录题目的信息,主表下分了四种题目表
如果我们想新增题目信息,不难想到,最简单、最直接的办法那肯定是在service层直接做多个if-else来调用多个dao(mapper)
@Override
public void add(SubjectInfoBO subjectInfoBO) {
if (log.isInfoEnabled()) {
log.info("SubjectInfoDomainServiceImpl.add.bo:{}", JSON.toJSONString(subjectInfoBO));
}
/*
* 假设都写在主流程里面
* 判断type,单选的调用单选的service,多选的调用多选的
* 一大堆if
*/
// 主表
SubjectInfo subjectInfo = SubjectInfoConverter.INSTANCE.convertBoToInfo(subjectInfoBO);
subjectInfoService.insert(subjectInfo);
// 一大堆if-else,然后不同的service
// ......Service.insert(......);
// 省略多表处理……
}
这样做?
其他人可能会好好问候你一下😁
这样的代码中,有很多if-else,并且还有很多的if-else嵌套,无论是可读性还是可维护性都非常低。
如果后续更改其中一个题型那么在原方法上更改很有可能会导致其他的插入出现异常。
那么这个策略模式怎么实现呢?
先定义一个重要的接口,我这里都定义在了handler里边了
public interface SubjectTypeHandler {
/**
* 枚举身份的识别
*
* @return
*/
SubjectInfoTypeEnum getHandlerType();
/**
* 实际的题目的插入
*
* @param subjectInfoBO
*/
void add(SubjectInfoBO subjectInfoBO);
}
然后定义四个题目类(单选、多选、判断、简答)分别实现这个接口
@Component
@RequiredArgsConstructor
public class BriefTypeHandler implements SubjectTypeHandler {
private final SubjectBriefService subjectBriefService;
/**
* 枚举身份的识别
*
* @return 哪个枚举出来的
*/
@Override
public SubjectInfoTypeEnum getHandlerType() {
return SubjectInfoTypeEnum.BRIEF; // 4 简答
}
/**
* 实际的题目的插入
*/
@Override
public void add(SubjectInfoBO subjectInfoBO) {
// 简答题目的插入
// set方法......
subjectBriefService.insert(subjectBrief);
}
}
在上面代码中,直接定义了一个枚举来表示type了
其他类和上面方法一致
上面的策略做完之后,我们需要定义一个工厂来做处理,这个工厂我也放在了上面一堆类的包下面,也就是handler中。
/**
* 题目类型处理器工厂
*/
@Component
public class SubjectTypeHandlerFactory implements InitializingBean {
@Resource
private List<SubjectTypeHandler> subjectTypeHandlerList;
private Map<SubjectInfoTypeEnum, SubjectTypeHandler> handlerMap = new HashMap<>();
public SubjectTypeHandler getHandler(int subjectType) {
SubjectInfoTypeEnum subjectInfoTypeEnum = SubjectInfoTypeEnum.getByCode(subjectType);
return handlerMap.get(subjectInfoTypeEnum);
}
/**
* 启动时加载
*
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
for (SubjectTypeHandler subjectTypeHandler : subjectTypeHandlerList) {
handlerMap.put(subjectTypeHandler.getHandlerType(), subjectTypeHandler);
}
}
}
这里实现了Spring的InitializingBean接口,InitializingBean是Spring提供的拓展性接口,InitializingBean接口为bean提供了属性初始化后的处理方法,它只有一个afterPropertiesSet方法,凡是实现该接口的类,在bean的属性初始化后都会执行该方法。
说人话就是,启动后直接加载……
这样呢,我们在调用service的时候,就不会有那么多的if-else了
public void add(SubjectInfoBO subjectInfoBO) {
if (log.isInfoEnabled()) {
log.info("SubjectInfoDomainServiceImpl.add.bo:{}", JSON.toJSONString(subjectInfoBO));
}
// 主表
SubjectInfo subjectInfo = SubjectInfoConverter.INSTANCE.convertBoToInfo(subjectInfoBO);
subjectInfoService.insert(subjectInfo);
// 调用工厂
SubjectTypeHandler handler = subjectTypeHandlerFactory.getHandler(subjectInfo.getSubjectType());
handler.add(subjectInfoBO);
// 关系表处理
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。