Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将异常作为方法参数处理_Java_Design Patterns_Exception Handling - Fatal编程技术网

Java 将异常作为方法参数处理

Java 将异常作为方法参数处理,java,design-patterns,exception-handling,Java,Design Patterns,Exception Handling,我正在寻找一种设计模式来处理作为方法参数接收的异常实例 为了说明问题的来龙去脉,我正在使用GWT,并且有各种异步处理程序,它们的形式通常类似于: public interface AsyncCallback<T> { void onFailure(Throwable caught); void onSuccess(T result); } 但在我看来,这看起来很难看。大型if..else if链与大量使用instanceof似乎是应该避免的事情 我想也许我可以使用tr

我正在寻找一种设计模式来处理作为方法参数接收的
异常
实例

为了说明问题的来龙去脉,我正在使用GWT,并且有各种异步处理程序,它们的形式通常类似于:

public interface AsyncCallback<T> {

  void onFailure(Throwable caught);

  void onSuccess(T result);

}
但在我看来,这看起来很难看。大型
if..else if
链与大量使用
instanceof
似乎是应该避免的事情

我想也许我可以使用
try…catch
构造来处理
异常
,方法如下:

void handleException(final Exception e) {
    if(e instanceof TimeoutException) {
        handleTimeout();
    } else if (e instanceof NoSuchElementException) {
        handleInvalidElement();
    } else {
        stopAndCatchFire();
    }
}
void handleException(final Exception e) {
    try {
        throw e;
    } catch (TimeoutException te) {
        handleTimeout();
    } catch (NoSuchElementException nsee) {
        handleInvalidElement();
    } catch (Exception ex) {
        stopAndCatchFire();
    }
}
但不知何故,这似乎是一种虐待。你认为第二种方法或者我可以采用的避免第一种情况的另一种方法有什么缺点吗

但在我看来,这看起来很难看。大的if..else if链加上instanceof的大量使用似乎是应该避免的

我不同意。我认为这段代码使用了这两种语言结构,这正是它们的本意。如果代码变得不可管理(子句太多),那么您应该质疑错误处理的一般方法,而不是该方法的细节。在那个阶段,您可能需要考虑AOP。


另一方面,第二种方法很可怕;)

应避免异常上的控制流,当然也不应处于onFailure状态。onFailure方法应该尽可能简单

修改异步运行的代码以处理异常情况。ElementNotFound异常可以通过在执行任何操作之前检查元素是否存在来处理。超时异常可以通过环绕可以超时的代码(调用Web服务或其他东西)来处理。。挡块。
然后扩展结果类型T,以包含超时发生或未找到元素的额外信息(如果需要)。

您是否不能拥有由异常处理程序处理的异常类型键入的异常处理程序字典,然后在获得异常时,在字典中查找异常类型的处理程序。如果有异常,则将异常传递给处理程序,如果没有异常,则使用默认处理程序

因此,您的处理程序如下所示:

void handleException(final Exception e) {
    if (handlers.containsKey(e.getType())
    {
        handlers[e.getType()].handle(e);
    }
    else
    {
         defaultHandler.handle(e);
    }
}
我的Java有点生疏,所以示例是c-sharpy,但应该足够简单,可以进行翻译(尽管我记得没有大写第一个字母:)

这种方法的优点是可以简单地添加新的处理程序

但是,如果子类型具有相同的处理程序,则会受到影响,因为必须显式注册每个子类型

要解决此问题,只需让每个处理程序负责决定是否可以处理异常:

public interface ExceptionHandler
{
     bool canHandle(Exception e);
     void handle(Exception e)
}

然后将处理程序放在一个列表中,迭代询问每个处理程序是否可以处理当前异常,当您找到一个可以处理当前异常的处理程序时,让它来处理它。

只需处理函数内异常中的if语句,就可以使处理程序更加优雅

void handleException(Exception e){
    handleOne(e)
    handleTwo(e)
    ...
}
它看起来更漂亮。当然,每个函数都会被调用,但它的第一行只是一个if语句。有一些变化-例如,使你的句柄函数成为guava函数对象,把它们放在一个列表中,然后迭代它们,直到你得到第一个返回“true”的函数。比如:

public class handlerOne implements Function<Exception, Boolean> {

    Boolean apply(Exception input) {        
        return handlerOne();
    }
}
void handleException(Exception e){
    list<Function<Exception, Boolean> list = Object.getHandlers(); //store your handlers somewhere
    for(Function<Exception, Boolean> f : list){
        if(f.apply(e)){
            break
        }
    }
}
公共类handlerOne实现函数{
布尔应用(异常输入){
返回handlerOne();
}
}
然后您的句柄函数可以是:

public class handlerOne implements Function<Exception, Boolean> {

    Boolean apply(Exception input) {        
        return handlerOne();
    }
}
void handleException(Exception e){
    list<Function<Exception, Boolean> list = Object.getHandlers(); //store your handlers somewhere
    for(Function<Exception, Boolean> f : list){
        if(f.apply(e)){
            break
        }
    }
}
void handleException(异常e){

ListSecond绝对是最糟糕的反模式。它的性能也非常差。第二个会有相当差的性能(尽管没有第一次抛出那么昂贵,因为大部分成本都在构建异常上)在概念上有点难看。你可以考虑获取异常名并在其上做一个<代码>开关>代码(虽然它不处理子类)。@djechlin很有意思。为什么你认为这是一个更糟糕的反模式?在第二种情况下,性能无疑会更差。@OliverWatkins-只有当最终的
捕获
不属于异常(或任何参数类型)时才是如此@HotLicks-switch-on-name之所以不起作用,完全是因为它不处理子类。必须添加子类会违反OCP。重点是。我不认为AOP是一个选项,因为它是GWT代码。但GWT在这方面有自己的方式和方法。它们真的很可怕。我不同意,onFailure方法应该很简单。通过在onFailure方法可以扩展实际上属于被调用到客户端逻辑的服务的逻辑,这使得它更难维护。就我个人而言,我会发现它更容易维护,因为您将错误处理功能封装到一个地方。显然,它有成为上帝对象的危险,但我认为这是错误的我完全同意你的第一句话,虽然我不认为这是一个基于异常的示例控制流,而是一个协调的异常处理程序——这通常是一件好事。这是一个非常聪明的想法!我会调查并回复你。请记住,使用这种方法你需要特定异常的每个子类型的处理程序。这可能是问题,也可能不是问题。@StuPointerException是的,我正在考虑使用Spring为其处理程序使用的模式,其中每个处理程序都有一个
canHandle
方法。这应该可以帮助我解决子类问题。@StuPointerException,是的,这是正确的,尽管我在进程中如果这确实是一个问题,请添加处理该问题的选项issue@SamHolder+1使用ExceptionHandler接口的不错的解决方案。