0

I have an interface that has ~30 methods and has two different implementations.

I am trying to create another implementation which will have some custom logic and at times it will call one of those existing implementations depending on some conditions.

The issue is that I only want this behavior for a subset of methods, let's say 10 methods.

public interface ITest {

void method1(Param1 param1);
void method2(Param2 param2);

}

public class TestImpl1 implements ITest {
void method1(Param1 param1){
//
}
void method2(Param2 param2){
//
}
}

Let's say, I only want to override method1 in the new implementation and that could call existing implementation in some of the cases.

Delegating the call from a new interface to existing one for method2 seems like a way but I am not sure if that's the best option. Any idea would be appreciated to make it look cleaner.

Thanks!

1
  • Do you mean that your class would have part own implementation, part Impl1 and part Impl2? Like if you were to create a diamond with multiple inheritance? Commented Nov 7, 2017 at 7:16

1 Answer 1

1

Will code call the methods you're not implementing? If not, you can just throw UnsupportedOperationException. Since it's a RuntimeException, it will still compile. If code is calling the methods you don't want to implement, you can automatically implement those methods and delegate to an existing implementation using InvocationHandler. This may be convenient because your interface is particularly long. For example:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class TestImpl1 implements InvocationHandler {
    private final ITest delegate1;
    private final ITest delegate2;

    public TestImpl1(ITest delegate1, ITest delegate2) {
        this.delegate1 = delegate1;
        this.delegate2 = delegate2;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        if (method.getName.equals("method1") {
            // choose delegate 1 or 2
            if (...) {
                method.invoke(delegate1, args);
            } else {
                method.invoke(delegate2, args);
            }
        } else {
            // for all other methods, delegate to delegate1
            method.invoke(delegate1, args);
        }
    }
}

You can use it like so:

ITest delegate1 = ...
ITest delegate2 = ...
// instantiate a proxy
ITest testImpl1 = (ITest) Proxy.newProxyInstance(ITest.class.getClassLoader(),
            new Class[] { ITest.class },
            new TestImpl1(delegate1, delegate2));
// use
testImpl1.method1(...)
testImpl1.method2(...)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.