我对以下方法的设计感到困惑:
Map<String, BigDecimal> foo(Parameter p){ ... }
此方法采用复杂的Parameter
并返回地图名称 - &gt;值。在许多情况下,基于参数的某些基础calue,结果映射将是相同的,此外,只有少数不同的映射可以返回,因此这些将被缓存。但是,在最初创建映射时,可能存在不同类型的错误 - 某些字符串值可能不正确,某些值可能是&lt;因此应该跳过0等等。这些错误可能具有不同的性质。我想返回这个地图,但是当执行每个地图的初始化时,也能够标记这些错误,理想情况下只能标记一次。最干净的方法是什么?
答案 0 :(得分:5)
这是一个相当不寻常的要求 - 如果可以生成有效的结果,尽管存在内部错误,您应该返回该结果;如果没有,抛出异常。
但如果您确实想要返回这些附加信息,那么我发现您有两种可供选择:
foo()
时,会累积某些字段中的内部错误。公开额外的getFooErrors()
方法以允许调用者检查发生的情况。如果您需要告诉来电者这些错误对结果地图质量的影响程度,可能还需要getFooErrorSeverity()
方法。 <强>不可变/功能即可。从上面返回信息(例外,可能是严重性分数)作为方法的一部分。而不是返回Map<String, BigDecimal>
,而是返回包含地图的对象以及异常详细信息。 E.g:
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()方法以允许调用者查看编写器是否遇到任何异常。
我更喜欢第二种,因为它不会影响线程安全性,它会为客户端预先提供所有信息,并且它与遇到错误的范围整齐地结合在一起。
答案 1 :(得分:2)
没有一种正确的方法可以做到这一点,但是如何创建包含地图和错误列表的特殊类FooResult
(尽管我宁愿将其称为警告,因为通常会报告不可恢复的错误例外),例如:
FooResult foo(Parameter p){ ... }
class FooResult {
Map<String, BigDecimal> result;
List<Error> errors;
}
其中Error
可以是包含您需要的所有错误信息的类(例如,代码,消息,异常等),例如:
class Error {
int code;
String message;
Throwable cause; // optional, depending on error
// ...
}
或者,Error
的列表可以作为参数传递,并在必要时由方法填充,例如:
Map<String, BigDecimal> foo(Parameter p, List<Error> errors) {
...
if (error) {
errors.add(new Error(10, "Bad error"));
}
}