消费者附上 try catch 逻辑不起作用
Consumer to enclose try catch logic does not work
我正在重构一些遗留代码并且遇到了这个函数:
private static void parseOptionalValues(Product product, Input source) {
try {
product.setProductType(...some operation with source...);
} catch (IllegalArgumentException ignored) {}
try {
product.setMaterial(...some operation with source...);
} catch (IllegalArgumentException ignored) {}
try {
product.setUnitPricingBaseMeasure(...some operation with source...);
} catch (IllegalArgumentException ignored) {}
try {
product.setUnitPricingMeasure(...some operation with source...);
} catch(IllegalArgumentException ignored){}
}
我的常识告诉我,为了保持 Don't Repeat Yourself 原则,我应该包装这个 try-catch 逻辑,所以我引入了这个更改:
private static void parseOptionalValues(Product product, Input source) {
setOptionalParameter(...some operation with source..., product::setProductType);
setOptionalParameter(...some operation with source..., product::setMaterial);
setOptionalParameter(...some operation with source..., product::setUnitPricingBaseMeasure);
setOptionalParameter(...some operation with source..., product::setUnitPricingMeasure);
}
private static <T> void setOptionalParameter(T value, Consumer<T> consumer) {
try {
consumer.accept(value);
} catch (IllegalArgumentException ignored) {}
}
我正在 运行 进行一些单元测试和调试,但代码的行为与以前不同,因为 IllegalArgumentException
未被捕获但被引发,因此程序失败。
关于如何解决将 try-catch 逻辑封装在一个地方的任何想法?
我认为问题可能是获取要传递给设置器的参数的代码抛出异常。因此,一种可能的方法是通过使用 Supplier
使代码的那部分 lazy,然后在 Supplier
中调用 .get()
try/catch
块(以及调用 Consumer
):
private static <T> void setOptionalParameter(
Supplier<? extends T> supplier,
Consumer<? super T> consumer) {
try {
consumer.accept(supplier.get());
} catch (IllegalArgumentException ignored) {
}
}
您可以按如下方式调用该方法:
setOptionalParameter(() -> ...some operation with source..., product::setProductType);
请注意,我已经改进了您的方法的签名,因此它现在分别接受 Supplier
和 Consumer
的更广泛的通用子类型和超类型。
编辑: 根据评论,上述方法可能不够灵活,即如果该方法接受多个参数等。在这种情况下,它将是最好使用 Runnable
实例:
private static void setOptionalParameter(Runnable action) {
try {
action.run();
} catch (IllegalArgumentException ignored) {
}
}
现在调用将变为:
setOptionalParameter(() -> {
ProductType productType = ...some operation with source...;
Material material = ...some operation with source...;
product.doSomethingWith2Args(productType, material);
});
我正在重构一些遗留代码并且遇到了这个函数:
private static void parseOptionalValues(Product product, Input source) {
try {
product.setProductType(...some operation with source...);
} catch (IllegalArgumentException ignored) {}
try {
product.setMaterial(...some operation with source...);
} catch (IllegalArgumentException ignored) {}
try {
product.setUnitPricingBaseMeasure(...some operation with source...);
} catch (IllegalArgumentException ignored) {}
try {
product.setUnitPricingMeasure(...some operation with source...);
} catch(IllegalArgumentException ignored){}
}
我的常识告诉我,为了保持 Don't Repeat Yourself 原则,我应该包装这个 try-catch 逻辑,所以我引入了这个更改:
private static void parseOptionalValues(Product product, Input source) {
setOptionalParameter(...some operation with source..., product::setProductType);
setOptionalParameter(...some operation with source..., product::setMaterial);
setOptionalParameter(...some operation with source..., product::setUnitPricingBaseMeasure);
setOptionalParameter(...some operation with source..., product::setUnitPricingMeasure);
}
private static <T> void setOptionalParameter(T value, Consumer<T> consumer) {
try {
consumer.accept(value);
} catch (IllegalArgumentException ignored) {}
}
我正在 运行 进行一些单元测试和调试,但代码的行为与以前不同,因为 IllegalArgumentException
未被捕获但被引发,因此程序失败。
关于如何解决将 try-catch 逻辑封装在一个地方的任何想法?
我认为问题可能是获取要传递给设置器的参数的代码抛出异常。因此,一种可能的方法是通过使用 Supplier
使代码的那部分 lazy,然后在 Supplier
中调用 .get()
try/catch
块(以及调用 Consumer
):
private static <T> void setOptionalParameter(
Supplier<? extends T> supplier,
Consumer<? super T> consumer) {
try {
consumer.accept(supplier.get());
} catch (IllegalArgumentException ignored) {
}
}
您可以按如下方式调用该方法:
setOptionalParameter(() -> ...some operation with source..., product::setProductType);
请注意,我已经改进了您的方法的签名,因此它现在分别接受 Supplier
和 Consumer
的更广泛的通用子类型和超类型。
编辑: 根据评论,上述方法可能不够灵活,即如果该方法接受多个参数等。在这种情况下,它将是最好使用 Runnable
实例:
private static void setOptionalParameter(Runnable action) {
try {
action.run();
} catch (IllegalArgumentException ignored) {
}
}
现在调用将变为:
setOptionalParameter(() -> {
ProductType productType = ...some operation with source...;
Material material = ...some operation with source...;
product.doSomethingWith2Args(productType, material);
});