梨小落是个小疯子

梨小落是个小疯子

背景

最近在做一个产品的版本设计功能,多个模块均涉及到版本管理,一开始着急上线,实现方式上是先完成一个模块的版本管理,把链路调通,然后上线。等到写其他模块的版本管理的时候,发现代码90%都是一样的,就不得不思考这种方式的优缺点。考虑到这种情况,想到了继承和泛型。

泛型定义

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。

 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

具体介绍移步该篇博客

设计方案

版本设计简介

在设计模块版本的时候,用到了两张表。一张active表,用于存放当前模块id & 当前生效的版本号;一张version表,用于存放当前模块id的所有版本列表;version表通过外键active_id进行关联。

具体设计

第一次真正使用泛型-LMLPHP

具体实现

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;
    }


}
02-19 01:37