【问题标题】:How to eliminate the duplicate try-catch code in similar methods?如何消除类似方法中重复的 try-catch 代码?
【发布时间】:2017-03-28 06:23:32
【问题描述】:

我的服务中有以下插入/更新方法:

@Override
public void insertEntity(Entity entity) {

  try {        
    entityDao.insert(entityMapper.entityToEntityDO(entity));

  } catch (DataIntegrityViolationException ex){

    if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
      SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
      if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
        throw new FieldCannotBeNullException(violationEx.getMessage());
      }
    }

    throw ex;
  }
}

@Override
public void updateEntity(Entity entity) {

  try {        
    entityDao.update(entityMapper.entityToEntityDO(entity));

  } catch (DataIntegrityViolationException ex){

    if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
      SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
      if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
        throw new FieldCannotBeNullException(violationEx.getMessage());
      }
    }

    throw ex;
  }
}

如您所见,insertEntityupdateEntity 的实际逻辑非常简单。为了抛出一个自定义的Exception,我做了一些数据库错误代码检查。由于这两种方法都需要这种检查,所以两种方法中的代码都重复了,这显然是代码异味。

如何消除这种重复代码?

【问题讨论】:

  • @Override注解:是否使用Java 8,有updateEntityinsertEntity-方法的超类或实现接口是什么?
  • 我只是将 catch 块中的代码放到一个单独的方法中。
  • 您可能会考虑摆脱异常作为控制流程的一种方式。我想象你所做的不仅仅是检查空列 - 所以调用这些方法的代码有很多异常处理要做。这在 Java 中是惯用的,但不是特别可读或高效......

标签: java refactoring code-duplication


【解决方案1】:

将公共 catch 块提取到一个抛出 DataIntegrityViolationException 的方法中。

【讨论】:

    【解决方案2】:

    你可以像这样创建接口:

    public interface ConsumerWithException<T, V extends Exception> {
        /**
         * Performs this operation on the given argument.
         *
         * @param t the input argument
         */
        void accept(T t) throws V;
    
    }
    

    使用私有方法,例如:

    private void action(ConsumerWithException<Entity, DataIntegrityViolationException> doAction, Entity entity){
        try {
            doAction.accept(entity);
        } catch (DataIntegrityViolationException ex){
    
            if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
                SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
                if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
                    throw new FieldCannotBeNullException(violationEx.getMessage());
                }
            }
    
            throw ex;
        }
    }    
    

    【讨论】:

      【解决方案3】:

      你可以把catch块里面的代码放到一个单独的方法中。

      或者,如果您希望将来在那里处理多个异常,您可以捕获 Exception 并编写一个处理程序方法来处理异常。

      【讨论】:

        【解决方案4】:

        您可以声明您的方法以引发异常,然后在调用您的方法的地方尝试/捕获。例如:

        public void insertEntity(Entity entity) throws DataIntegrityViolationException {} 
        public void updateEntity(Entity entity) throws DataIntegrityViolationException {}  
        try {
          insertEntity(entity);
          updateEntity(entity);
        catch (DataIntegrityViolationException e) {
          // handle exception
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-29
          • 1970-01-01
          • 2021-03-29
          • 2016-12-25
          相关资源
          最近更新 更多