背景
最近在做一个产品的版本设计功能,多个模块均涉及到版本管理,一开始着急上线,实现方式上是先完成一个模块的版本管理,把链路调通,然后上线。等到写其他模块的版本管理的时候,发现代码90%都是一样的,就不得不思考这种方式的优缺点。考虑到这种情况,想到了继承和泛型。
泛型定义
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
具体介绍移步该篇博客。
设计方案
版本设计简介
在设计模块版本的时候,用到了两张表。一张active表,用于存放当前模块id & 当前生效的版本号;一张version表,用于存放当前模块id的所有版本列表;version表通过外键active_id进行关联。
具体设计
具体实现
BaseService
/*** * 版本统一服务 * * @author lixiaoluo * @since 2019/02/13 * @param <BO> * @param <DO> * @param <DTO> */ public interface BaseService<BO extends BaseVersionBO, DO extends BaseVersionDO, DTO extends BaseVersionDTO, ActiveDO extends BaseActiveDO>{ /*** * get * * @param activeId * Query_active中的id * @return * @throws Exception */ public Result<BO> get(Long activeId); /*** * publish * * @param dao * @return */ public Result<Boolean> publish(DTO dao); /*** * offline * * @param id * 要下线的id * @return */ public Result<Boolean> offline(Long activeId); /*** * *getVersionMapper * @return */ public BaseVersionMapper getVersionMapper(); /*** * *getActiveMapper * @return */ public BaseVersionMapper getActiveMapper(); }
抽象类实现VersionService
/**** * 统一服务 * * @author lixiaoluo * @since 2019/02/12 * @param <D> * DO * @param <B> * BO * @param <DT> * DTO */ public abstract class VersionService<BO extends BaseVersionBO, DO extends BaseVersionDO, DTO extends BaseVersionDTO, ActiveDO extends BaseActiveDO>{ Logger logger = LoggerFactory.getLogger(VersionService.class); ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); /*** * 得到当前需要使用的activeMapper * * @return */ protected abstract BaseActiveMapper<ActiveDO> getActiveMapper(); /*** * 得到当前需要使用的versionMapper * * @return */ protected abstract BaseVersionMapper<DO> getVersionMapper(); @Override public Result<BO> get(Long activeId) { BO bo = ofBO(); // ... return Result.ofSuccess(bo); } /** 发布 */ @Override @Transactional(propagation = Propagation.SUPPORTS) public Result<Boolean> publish(DTO dao) { // publish return Result.ofSuccess(true); } /** 下线 */ @Override @Transactional(propagation = Propagation.SUPPORTS) public Result<Boolean> offline(Long activeId, String nick, Integer bucId) { // offline return Result.ofSuccess(true); } /*** * ofBO * * @return */ private BO ofBO() { Class<BO> boClass = (Class<BO>) pt.getActualTypeArguments()[0]; try { return boClass.newInstance(); } catch (InstantiationException e) { logger.error("实体对象BO类型获取失败", e); } catch (IllegalAccessException e) { logger.error("实体对象BO类型获取失败", e); } return null; } /*** * ofDO * * @return */ private DO ofDO() { Class<DO> boClass = (Class<DO>) pt.getActualTypeArguments()[1]; try { return boClass.newInstance(); } catch (InstantiationException e) { logger.error("实体对象DO类型获取失败", e); } catch (IllegalAccessException e) { logger.error("实体对象DO类型获取失败", e); } return null; } /*** * ofDTO * * @return */ private DTO ofDTO() { Class<DTO> boClass = (Class<DTO>) pt.getActualTypeArguments()[2]; try { return boClass.newInstance(); } catch (InstantiationException e) { logger.error("实体对象DTO类型获取失败", e); } catch (IllegalAccessException e) { logger.error("实体对象DTO类型获取失败", e); } return null; } /*** * ofActiveDO * * @return */ private ActiveDO ofActiveDO() { Class<ActiveDO> boClass = (Class<ActiveDO>) pt.getActualTypeArguments()[3]; try { return boClass.newInstance(); } catch (InstantiationException e) { logger.error("实体对象DO类型获取失败", e); } catch (IllegalAccessException e) { logger.error("实体对象DO类型获取失败", e); } return null; } }
具体类实现FormVersionServiceImpl
/** * 组件实例服务 * * @author SQI */ @Service public class ConfigFormVersionServiceImpl extends VersionService<ConfigFormVersionBO, ConfigFormVersionDO, ConfigFormVersionDTO, ConfigFormActiveDO> implements ConfigFormVersionService { Logger logger = LoggerFactory.getLogger(ConfigFormVersionServiceImpl.class); @Autowired private FormVersionMapper versionMapper; @Autowired private FormActiveMapper activeMapper; @Override protected BaseActiveMapper<ConfigFormActiveDO> getActiveMapper() { return activeMapper; } @Override protected BaseVersionMapper<ConfigFormVersionDO> getVersionMapper() { return versionMapper; } }