What is the best way to implement an interface that combines some instances of the same interface in various specified ways? I need to do this for multiple interfaces and I want to minimize the boilerplate and still achieve good efficiency, because I need this for a critical production system.
Here is a sketch of the problem.
Abstractly, I have a generic combiner class which takes the instances and specify the various combinators:
class Combiner<I> {
I[] instances;
<T> T combineSomeWay(InstanceMethod<I,T> method) {
// ... method.call(instances[i]) ... combined in some way ...
}
// more combinators
}
Now, let's say I want to implement the following interface among many others:
Interface Foo {
String bar(int baz);
}
I want to end up with code like this:
class FooCombiner implements Foo {
Combiner<Foo> combiner;
@Override
public String bar(final int baz) {
return combiner.combineSomeWay(new InstanceMethod<Foo, String> {
@Override public call(Foo instance) { return instance.bar(baz); }
});
}
}
Now, this can quickly get long and winded if the interfaces have lots of methods. I know I could use a dynamic proxy from the Java reflection API to implement such interfaces, but method access via reflection is hundred times slower. So what are the alternatives to boilerplate and reflection in this case?
You can reverse your combiners:
Not a one-liner but easier to understand. That would be more complex if your methods throw exceptions though. You will need try/catch block and
addException
method.I would have suggested dynamic proxies - is it really so much slower than a regular method call these days - I've heard that reflection does quite a bit of magic under the covers to speed repeated method calls. (And if it is 100x slower, are you sure you will you notice? Ok, just re-read your question - you'll notice!)
Otherwise, you basically have the solution in your question: Use a Command object to wrap each method in your interface. You can then pass each instance in the collection of interfaces to the command object for processing.
Of course, if you're feeling brave and adventurous, you could generate the implementation of your command objects, and the implementation of the combiner interface using dynamic class generation, with cglib, javassist, orther dynamic bytecode generator. That would avoid the boilerplate.
You may also have some success with aspects, particularly aspectJ with compile-time or load-time weaving, so you avoid reflection overhead. Sorry I can't give details.