Да, вы можете сделать это на Java с помощью Proxys и отражения. Я делал это раньше. Дополнительную проблему, о которой вы должны беспокоиться, - это методы, возвращающие значения. Если вы завершаете несколько реализаций, возвращающих значение, вы действительно возвращаетесь?
В моем решении, я использую перечисление сказать класс либо возвращать первый результат из списка или последнего результата (в любом случае все делегаты называются)
Вот мой код
/**
* {@code MultipleWrapper} uses dymanic proxies to wrap
* several instances of an interface. This allows
* all wrapped instances to be called by only a single
* call to the wrapper.
* @author dkatzel
*/
public final class MultipleWrapper<T> implements InvocationHandler{
private final ReturnPolicy policy;
private final List<T> delegates = new ArrayList<T>();
/**
* Since methods can only return a single
* return value, only one of the wrapped
* methods can be returned to the caller (even though
* they will all be called).
* @author dkatzel
*/
public static enum ReturnPolicy{
/**
* Return the first wrapped instance.
*/
RETURN_FIRST,
/**
* Return the last wrapped instance.
*/
RETURN_LAST
}
/**
* Create a dynamic proxy to wrap the given delegate instances.
* @param <T> the interface to proxy.
* @param <I> the instances of T.
* @param classType the class object of T.
* @param policy the return policy to use on methods that return something.
* @param delegates the list of delegates to wrap in the order in which
* they will be called.
* @return a new instance of T that wraps the delegates.
* @throws IllegalArgumentException if no delegates are given
* @throws NullPointerException if classType ==null or policy ==null or any delegate ==null.
*/
@SuppressWarnings("unchecked")
public static <T, I extends T> T createMultipleWrapper(Class<T> classType,ReturnPolicy policy, Iterable<I> delegates){
return (T) Proxy.newProxyInstance(classType.getClassLoader(), new Class<?>[]{classType},
new MultipleWrapper<T>(policy,delegates));
}
/**
* Convenience constructor which is the same as calling
* {@link #createMultipleWrapper(Class, ReturnPolicy, Object...)
* createMultipleWrapper(classType,ReturnPolicy.RETURN_FIRST,delegates)}
* @see #createMultipleWrapper(Class, ReturnPolicy, Object...)
*/
public static <T,I extends T> T createMultipleWrapper(Class<T> classType,Iterable<I> delegates){
return createMultipleWrapper(classType,ReturnPolicy.RETURN_FIRST,delegates);
}
/**
* Convenience constructor which is the same as calling
* {@link #createMultipleWrapper(Class, ReturnPolicy, Object...)
* createMultipleWrapper(classType,ReturnPolicy.RETURN_FIRST,delegates)}
* @see #createMultipleWrapper(Class, ReturnPolicy, Object...)
*/
@SafeVarargs
public static <T,I extends T> T createMultipleWrapper(Class<T> classType,I... delegates){
return createMultipleWrapper(classType,ReturnPolicy.RETURN_FIRST,Arrays.asList(delegates));
}
/**
* Convenience constructor which is the same as calling
* {@link #createMultipleWrapper(Class, ReturnPolicy, Object...)
* createMultipleWrapper(classType,ReturnPolicy.RETURN_FIRST,delegates)}
* @see #createMultipleWrapper(Class, ReturnPolicy, Object...)
*/
@SafeVarargs
public static <T,I extends T> T createMultipleWrapper(Class<T> classType,ReturnPolicy policy,I... delegates){
return createMultipleWrapper(classType,policy,Arrays.asList(delegates));
}
private MultipleWrapper(ReturnPolicy policy,Iterable<? extends T> delegates){
if(policy==null){
throw new NullPointerException("policy can not be null");
}
this.policy = policy;
for(T delegate : delegates){
if(delegate ==null){
throw new NullPointerException("delegate can not be null");
}
this.delegates.add(delegate);
}
if(this.delegates.size()==0){
throw new IllegalArgumentException("must wrap at least one delegate");
}
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
List<Object> returns = new ArrayList<Object>(delegates.size());
try{
for(T delegate :delegates){
returns.add(method.invoke(delegate, args));
}
if(policy == ReturnPolicy.RETURN_LAST){
return returns.get(returns.size()-1);
}
return returns.get(0);
}catch(InvocationTargetException e){
throw e.getCause();
}
}
}
Затем, чтобы использовать его вы можете сделать что-то вроде этого:
List<Type> listeners = ...
Type wrappedListener = MultipleWrapper.createMultipleWrapper(Type.class, listeners);
в Java, вы не знаете, что 'T' является' interface' против в 'class'. Не знаю, есть ли другие варианты языка. –
Вы можете сделать это на C++, потому что 'GenericComposite' - это шаблон - совсем другая вещь из Java generic. –
dasblinkenlight