处理这些if子句的更简洁方法?

时间:2019-02-06 10:49:58

标签: java if-statement

我想知道哪种更干净的方式来处理这堆if子句。作为附加信息,它是Spark Framework研究项目中使用的异常处理程序。

这段代码可以完成工作并且可读,但是可能的进一步扩展会将其转换为怪兽。您有重构建议吗?

    public ExceptionHandler<? super java.lang.Exception> handler() {
        return (e, request, response) -> {
            ErrorMessage error;

            if (e instanceof SomeException1) {
                response.status(422);
                error = new ErrorMessage("message1", e.getMessage());
            } else if (e instanceof SomeException2) {
                response.status(404);
                error = new ErrorMessage("message2", e.getMessage());
            } else if (e instanceof SomeException3) {
                response.status(500);
                error = new ErrorMessage("message3", e.getMessage());
            } else {
                response.status(500);
                error = new ErrorMessage("message4", e.getMessage());
            }

            [...]
        };
    }

为澄清起见进行编辑:

这段代码是异常处理程序方法的一部分,该方法使用Spark的exception()方法在应用程序的主类中注册。像这样:

public class MainClass {

    public static void main(String[] args) {
      //register the exception handler
      exception(Exception.class, errorsHandler.handler()); //handler() is the method showed above.
    }    
}

2 个答案:

答案 0 :(得分:4)

避免长if- / else链的好方法是使用映射表。您可以使用Map,它将Exception类映射到状态代码。像这样:

private static Map<Class<?>, Integer> errorCodeMapping = new HashMap<>();

{
    errorCodeMapping.put(SomeException.class, 422);
    ...
}

然后您的异常处理程序将代码设置为

response.status(errorCodeMapping.get((e.getClass()));

对于异常类到错误消息的映射,可以执行相同的操作。 这样,您还可以为新映射提供一个设置器,而不必将其硬编码到Handler类本身中。

答案 1 :(得分:1)

我的版本将如下所示:

class ExceptionInfo {
   Class<? extends Exception> cls;
   int errCode;
   String message;

   public ExceptionInfo(Class<? extends Exception> cls, int errCode, String message) {
       this.cls = cls;
       this.errCode = errCode;
       this.message = message;
   }
}

// Note that the last item is Exception.class, to serve as a default.

final static List<ExceptionInfo> EXCEPTION_LIST = Arrays.asList(
    new ExceptionInfo( SomeException1.class, 422, "message1"),
    new ExceptionInfo( SomeException2.class, 404, "message2"),
    new ExceptionInfo( SomeException3.class, 500, "message3"),
    new ExceptionInfo( Exception.class, 500, "message4" )
);

ExceptionInfo searchException( Exception e ) {
    return EXCEPTION_LIST.stream()
        .filter( info -> info.cls.isInstance(e) )
        .findFirst()
        .orElseThrow( IllegalStateException::new );
}

这样,您可以使ExceptionInfo与给定的e兼容,然后使用其errCodemessage。这与instanceOf完全兼容。当然,您可以使用getter代替直接访问此迷你类的字段。