Это не так просто, как ответ Томаса Прейслера, но поможет вам вообще не повторять какой-либо метод. Поэтому, если вы расширяете интерфейс, вам нужно изменить только конкретные классы, а не компоновщик, который описывает фактическое поведение, которое вы хотите.
Создайте интерфейс, содержащий все методы 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());
person
Olivier Grégoire
schedule
15.09.2020
Wrapper.m1(s);
вызовов в своем коде? - person Kayaman   schedule 15.09.2020