检查和处理对象时使用continue或Checked Exceptions


3

我正在处理一个“文档”对象列表。在我成功记录文档的处理之前,我首先要检查几件事情。比方说,文件应该存在,文件中应该有文件。只是对这个例子进行了两个简单的检查,但在我成功处理了我的文档之前再考虑8次检查。

你会偏好什么?

for (Document document : List<Document> documents) { 
    if (!fileIsPresent(document)) { 
     doSomethingWithThisResult("File is not present"); 
     continue; 
    } 
    if (!isSomethingInTheDocumentPresent(document)) { 
     doSomethingWithThisResult("Something is not in the document"); 
     continue; 
    } 
    doSomethingWithTheSucces(); 
} 

或者

for (Document document : List<Document> documents) { 
    try { 
     fileIsPresent(document); 
     isSomethingInTheDocumentPresent(document); 
     doSomethingWithTheSucces(); 
    } catch (ProcessingException e) { 
     doSomethingWithTheExceptionalCase(e.getMessage()); 
    } 
} 

public boolean fileIsPresent(Document document) throws ProcessingException { 
    ... throw new ProcessingException("File is not present"); 
}  

public boolean isSomethingInTheDocumentPresent(Document document) throws ProcessingException { 
    ... throw new ProcessingException("Something is not in the document"); 
} 

什么是更具可读性。什么是最好的?有没有更好的方法来做到这一点(也许使用某种设计模式)?

至于可读性去我的偏好是目前异常变种...

什么是你的吗?

4

我认为重构您的支票更具可读性。

for (Document document : List<Document> documents) { 
    if(checkDocument(document)) { 
     doSomethingWithTheSucces(); 
    } else { 
     doSomethingWithTheError(); 
    } 
} 

// Later: 
public boolean checkDocument(Document doc) { ... } 

如果你不需要知道它为什么失败则您checkDocument()可以只返回一个布尔值,也许日志的问题是什么。如果你的代码需要知道是什么问题,那么这样的事情:

for (Document document : List<Document> documents) { 
    try { 
     checkDocument(document); 
     doSomethingWithTheSucces(); 
    } catch(CheckDocumentException ex) { 
     doSomethingWithTheError(ex); 
    } 
} 

// Later: 
public void checkDocument(Document doc) throws CheckDocumentException { ... } 

你也可以有checkDocument()返回某种类型的返回码而不是例外情况,但我认为,例外的是处理好复杂的错误数据。

这两个选项都不需要继续或大的try块,并且通常使代码更具可读性。如果您需要稍后在其他地方执行此操作,它还可以让您重用检查文档的逻辑。

  0

或者甚至可以(document.isValid())...很好!感谢在思考这个问题上的转折... 23 9月. 082008-09-23 20:56:59

  0

Document是有效的看起来更多的OOP。也许你可以把所有的代码放在Document类中。 24 9月. 082008-09-24 03:40:27

  0

我是(可能错误地)假设Document类是密封的或内置类,而不是自定义类。另外,在Document上写一个isValid()方法只有在Document知道什么是有效的和什么不能的时候才有效。根据验证的作用,它可能没有足够的信息来说明。 24 9月. 082008-09-24 13:02:11


0

它更多地取决于这两个条件对于您正在处理的工作流程和上下文有多重要。

如果“预期的环境”是文件存在并且每个文档中都有内容,那么您会想要抛出一个异常,因为这是超出规范的东西,需要在特殊情况下处理。

如果“预期环境”是文件来来往往,有些文件有内容,有些则不需要,但重要的是要通过传入的文件列表,然后有一个优美的继续声明,并且潜在地记录或警告不良数据将是更可取的。


0

我的意愿是只在情况确实异常时才使用例外情况。

例如,作为编码人员,我们很自然地认为事实上有一个文件供我们处理。如果该文件不存在,那么您有一个特殊的,也许是不可恢复的情况来处理。

但是,如果文件中缺少某些内容,则可能不那么严重或更常见。例如,如果您正在设置初始参数列表,并且用户未能指定您期望的某个参数,则可能会回退到默认设置。由于我们向最终用户公开了一些配置脚本和属性文件,因此这种行为被认为是我们系统中的一项功能。

如果您抛出异常,退出处理循环,则无法恢复。但是,如果您只是在循环内抛出异常以指示“缺少规格,使用默认值”,我认为这不值得付出努力。

总之,我认为这取决于。在上面的具体示例中,我想我最终会使用这两种样式的组合。


1

继续使用,特别是在循环中。大多数异常都会创建一个堆栈跟踪,这可能是一个紧密循环中的主要性能问题。您需要重写fillInStackTrace以避免命中。

Stylistcally虽然,一般的规则是异常应在特殊情况下抛出。如果您正在查看文档是否存在并且有某些数据,则应继续使用,除非您对所有数据都有非常高的期望。但是,如果文件不存在或与格式不匹配,只是意外发生,请不要使用例外。


1

这不是关于可读性,而是关于安全编程。如果您检测到错误,则应确保客户端代码不能忽略它,除非它明确决定这样做(例如,重试)。

此外,'if'语句由于手动重构而更易于意外地破坏逻辑。

而且,正如您在自己的示例中看到的那样,通过异常进行错误报告的可读性更高。

P.S.就个人而言,我更喜欢使用未经检查的例外。但这取决于你所做的代码的类型。如果发生任何异常,Mine没有理由继续下去,所以我只是将它推荐到最顶端的代码,我将它报告。在这种情况下,未检查的异常是较少的工作。