我想知道哪种更干净的方式来处理这堆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.
}
}
答案 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
兼容,然后使用其errCode
和message
。这与instanceOf
完全兼容。当然,您可以使用getter代替直接访问此迷你类的字段。