3

我对该方法的以下设计感到困惑:

Map<String, BigDecimal> foo(Parameter p){ ... }

此方法接受一个复数Parameter并返回一个地图名称 -> 值。在许多情况下,基于参数的某些基础计算,生成的地图将是相同的,此外,只有少数不同的地图可以返回,因此这些地图将被缓存。但是,最初创建地图时,可能存在不同类型的错误 - 某些字符串值可能不正确,某些值可能 < 0,因此应该跳过等。这些错误可能具有不同的性质。我想返回这张地图,但也能够标记这些错误,理想情况下只有一次,当执行每个地图的初始化时。最干净的方法是什么?

4

2 回答 2

5

这是一个相当不寻常的要求——如果尽管存在内部错误,您仍能生成有效结果,那么您可能应该返回该结果;如果没有,则抛出异常。

但是,如果您确实想返回此附加信息,那么我看到您有两种选择:

  1. 面向对象,可变状态。运行时foo(),在某个字段中累积任何内部错误。公开一个额外的getFooErrors()方法来允许调用者检查发生了什么。getFooErrorSeverity()如果您需要告诉调用者这些错误对结果图质量的影响程度,可能还有一种方法。
  2. 不可变/功能。作为您方法的一部分,返回上面的信息(例外情况,可能还有严重性评分)。不是返回 a Map<String, BigDecimal>,而是返回一个包含地图的对象,以及异常详细信息。例如:

    public class FooResult {
        public final Map<String, BigDecimal> result;
        public final List<Throwable> errors;
        public final int errorSeverity;
    
        // Constructor elided
    }
    

第一种方法类似于java.io.PrintWriter标准库中的工作方式。它吞下其 I/O 方法遇到的任何 IOExceptions,并公开一个checkError()方法以允许调用者查看编写器是否遇到任何异常。

我更喜欢第二种,因为它不会影响线程安全,它会预先为客户端提供所有信息,并且它与遇到错误的范围巧妙地结合在一起。

于 2012-10-29T12:59:49.017 回答
2

没有一种正确的方法可以做到这一点,但是如何创建FooResult包含您的地图和错误列表的特殊类(尽管我宁愿将其称为警告,因为通常会报告不可恢复的错误与异常),例如:

FooResult foo(Parameter p){ ... }

class FooResult {
  Map<String, BigDecimal> result;
  List<Error> errors;
}

whereError可以是一个包含您需要的所有错误信息(例如代码、消息、异常等)的类,例如:

class Error {
  int code;
  String message;
  Throwable cause; // optional, depending on error
  // ...
}

或者,可以将 s 的列表Error作为参数传递,并在必要时由方法填充,例如:

Map<String, BigDecimal> foo(Parameter p, List<Error> errors) { 
  ... 
  if (error) {
    errors.add(new Error(10, "Bad error"));
  }
}
于 2012-10-29T12:55:42.513 回答