【发布时间】:2021-09-21 20:04:11
【问题描述】:
首先,抱歉标题不好,但我发现用一句话概括我的问题有点困难......
我们的软件中有一些我很不满意的代码。它是这样的:
@FunctionalInterface
public interface OneArgCall<T, U, A> {
T execute(U u, A arg);
}
@FunctionalInterface
public interface TwoArgCall<T, U, A, B> {
T execute(U u, A arg, B arg2);
}
public <T, U, A, B> T execCall(String x, Class<U> c, OneArgCall<T, U, A> call, A arg) {
U u = doSomething(x, c);
try {
return call.execute(u, arg);
} catch (SomeException se) {
handleSe(se);
} catch (SomeOtherException soe) {
handleSoe(soe);
}
public <T, U, A, B> T execCall(String x, Class<P> c, TwoArgCall<T, U, A, B> call, A arg, B arg2) {
U u = doSomething(x, c);
try {
return call.execute(u, arg, arg2);
} catch (SomeException se) {
handleSe(se);
} catch (SomeOtherException soe) {
handleSoe(soe);
}
即除了作为第三个参数传递的功能接口(当然还有该接口的参数列表)之外,execCall 方法是相同的。现在,我仍然可以忍受它,但还有更多这些方法(想象一下 ThreeArgCall、FourArgCall...)——这就是它变得难以忍受的地方。
那么,以所有 DRY 的名义:您将如何清理这段代码?我想像T execCall(String x, Class<U> c, SOMETHING, SOMETHING_ELSE) 这样的东西,其中 SOMETHING 可以是 OneArgCall、TwoArgCall... 接口中的任何一个,而 SOMETHING_ELSE 代表参数列表(?)。
这可以做到吗?或者有没有其他方法可以重构这段代码以减少重复性?
【问题讨论】:
-
您可以删除 execCall 的重复项,方法是让它只接受一个接口并将其发送到包装原始接口和参数并委托给它们的 execCall 适配器。这意味着 execCalls 中的代码更少,但其他地方的代码更多。适配器将具有统一的接口,这意味着参数必须包装在统一的基类中,并且特定的适配器必须向下转换为它们知道其实际目标接口需要的参数类型。
-
@gonen 请删除评论。
标签: java generics lambda dry functional-interface