学分去霍尔格!我真的很喜欢他提出的质疑null
. 因此,通过一个简短的示例,我想给他的方法更多的空间,即使对于这个用例有点复杂。
interface ConversionResult<T> {
String raw();
default Optional<T> value(){
return Optional.empty();
}
default Optional<String> error(){
return Optional.empty();
}
default void ifOk(Consumer<T> okAction) {
value().ifPresent(okAction);
}
default void okOrError(Consumer<T> okAction, Consumer<String> errorAction){
value().ifPresent(okAction);
error().ifPresent(errorAction);
}
static ConversionResult<LocalDate> ofDate(String raw, String pattern){
try {
var value = LocalDate.parse(raw, DateTimeFormatter.ofPattern(pattern));
return new Ok<>(raw, value);
} catch (Exception e){
var error = String.format("Invalid date value '%s'. Expected pattern '%s'.", raw, pattern);
return new Error<>(raw, error);
}
}
// more conversion operations
}
record Ok<T>(String raw, T actualValue) implements ConversionResult<T> {
public Optional<T> value(){
return Optional.of(actualValue);
}
}
record Error<T>(String raw, String actualError) implements ConversionResult<T> {
public Optional<String> error(){
return Optional.of(actualError);
}
}
用法类似于
var okConv = ConversionResult.ofDate("12.03.2020", "dd.MM.yyyy");
okConv.okOrError(
v -> System.out.println("SUCCESS: "+v),
e -> System.err.println("FAILURE: "+e)
);
System.out.println(okConv);
System.out.println();
var failedConv = ConversionResult.ofDate("12.03.2020", "yyyy-MM-dd");
failedConv.okOrError(
v -> System.out.println("SUCCESS: "+v),
e -> System.err.println("FAILURE: "+e)
);
System.out.println(failedConv);
这导致以下输出...
SUCCESS: 2020-03-12
Ok[raw=12.03.2020, actualValue=2020-03-12]
FAILURE: Invalid date value '12.03.2020'. Expected pattern 'yyyy-MM-dd'.
Error[raw=12.03.2020, actualError=Invalid date value '12.03.2020'. Expected pattern 'yyyy-MM-dd'.]
唯一的小问题是toString
现在打印的actual...
变体。当然,我们不需要为此使用记录。