Java,返回新的MyException:反模式?

Java,返回新的MyException:反模式?,java,exception,exception-handling,Java,Exception,Exception Handling,在我的课堂上,我正在验证自定义数据。许多条件适用。一旦失败,我想抛出一个特定的MyException。抛出此MyException需要许多公共参数和一个自定义参数(基于实际失败)。因此,实际的抛出需要许多字符来编写,并且由于代码重复而破坏了整洁。而且我不得不扔太多次。我决定创建一个私有方法,它准备并返回这个MyException的一个新实例,并将唯一的自定义数据作为参数,因此代码可以更简洁 private MyException createMyException(final CustomErr

在我的课堂上,我正在验证自定义数据。许多条件适用。一旦失败,我想抛出一个特定的MyException。抛出此MyException需要许多公共参数和一个自定义参数(基于实际失败)。因此,实际的抛出需要许多字符来编写,并且由于代码重复而破坏了整洁。而且我不得不扔太多次。我决定创建一个私有方法,它准备并返回这个MyException的一个新实例,并将唯一的自定义数据作为参数,因此代码可以更简洁

private MyException createMyException(final CustomErrorData errorData)
{
... some info gathering, parameterizing, etc... 
return new MyException(errorData);
}

所以抛出一个新的MyException要短得多:

throw createMyException(errorData);

我的问题是:在这种情况下,防止代码重复的正确做法是什么?我可能对异常估计过高。

如果你的helper函数非常好,我看不到其他更可取的方法。

我会在方法中抛出异常,除非这会混淆编译器

private void throwMyException(final CustomErrorData errorData) {
... some info gathering, parameterizing, etc... 
    throw new MyException(errorData);
}

throwMyException(errorData);


如果您有一种常规类型的异常,您将失去OOP的一些优势

您不需要为特定异常类型设置try-catch,而需要为常规异常设置catch,然后根据MyException类中的某些字段继续处理

您将有如下内容:

try{
    //code here
}
catch (MyException ex){
  switch(ex.exceptionType){
     case IOException: doSomething();break;
     case ConnectionException:doSomethingElse();break;
     default: //throw the exception outwards if you don't want to process it
 }
}
相反,你应该有

try{
    //code here
}
catch (IOException ex){
    doSomething();
    }
catch (ConnectionException ex){
    doSomethingElse();
}
更清晰,更面向对象


为什么要将所有异常放在一个通用类型下是一个谜,这就像让所有对象都成为一个类的实例一样,但是您需要根据一些标志对它们进行不同的行为。

我将这两个问题分开。您的类知道如何收集信息,但不必知道异常(该信息的用户)

首先定义创建
CustomErrorData
实例的方法:

private CustomErrorData createCustomErrorData() {
    // info gathering
    return new CustomErrorData(something);
}
然后为使用
CustomErrorData
的异常定义构造函数:

public MyException(CustomErrorData errorData) {
    // save it as a field
}
然后

在你需要的地方

这还允许您使用
CustomErrorData
进行其他操作,例如记录、向用户显示等等。

一个异常工厂-以前从未见过,但至少听起来是一个正确的设计

我只是担心——您似乎在设计异常抛出框架上投入了大量精力:向异常添加参数、状态等。您真的在代码中遇到过那么多异常情况吗?或者,在适当处理预期条件可能导致异常的情况下,是否抛出异常

通常抛出的异常是“仅针对日志”。发生了在当前环境下不应该发生的事情。在下一个版本中,开发人员应该知道并纠正这些问题。我们不应该使用异常来处理预期状态


因此,在研究brilliant异常创建代码之前,请仔细检查它是否值得付出努力,或者应用程序的设计是否开始变得。。。太有创意了。

CreateMeyException()是否使用任何类字段或方法来创建它?如果没有,您可能只能为您的异常使用多个构造函数。whtout查看您在
中的操作。。。一些信息收集、参数化等。
这是很难做出判断的,但是使用
构造函数
将是最干净的OOA设计方法,这就是它们的用途。这是他定义的类MyException,所以我假设他可以定义一个公共字段
public MyException(CustomErrorData errorData) {
    // save it as a field
}
throw new MyException(createCustomErrorData());