这并不像Thomas Preißler's answer 那样简单,但它可以帮助您完全不重复任何方法。所以如果你扩展接口,你只需要修改具体的类,而不是描述你想要的实际行为的链接器。
创建一个包含RealApi的所有方法的接口:
interface Api {
Type1 m1(String s);
}
然后是一个进行实际调用的类:
class ConcreteApi implements Api {
public Type1 m1(String s) {
return RealApi.m1(s);
}
}
然后创建你的 FakeApi:
class TotallyFakeApi implements Api {
public Type1 m1(String s) {
return FakeApi.m1(s);
}
}
现在,避免重复自己的棘手部分:
private static Object callImplementation(Api api, Method method, Object[] methodArgs) throws Exception {
Method actualMethod = api.getClass().getMethod(actualMethod.getName(), actualMethod.getParameterTypes());
return actualMethod.invoke(api, methodArgs);
}
Api fakeOrReal(Api fakeApi, Api realApi) {
return (Api) Proxy.newProxyInstance(
FakeApi.class.getClassLoader(),
new Class[]{Api.class},
(proxy, method, methodArgs) -> {
try {
Object r = callImplementation(fakeApi, method, methodArgs);
if (r != null) {
return r;
}
} catch (Exception e) {
// logError(e);
}
return callImplementation(realApi, method, methodArgs);
}
);
}
像这样获取实际的实现:
Api apiToUse = fakeOrReal(new TotallyFakeApi(), new ConcreteApi());