예 Proxys 및 리플렉션을 사용하여 Java에서이 작업을 수행 할 수 있습니다. 나는 그것을 전에했다. 걱정해야 할 추가 문제는 값을 반환하는 메서드입니다. 여러 구현을 래핑하는 경우 반환 값은 실제로 반환합니까? 내 솔루션에서
, 나는 목록 또는 최종 결과 (모든 대표가 호출 어느 쪽이든) 여기
에서 첫 번째 결과를 반환하거나 클래스를 알려 열거를 사용하여 내 코드의
/**
* {@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);
자바에서는 T'는'class' 대'interface'입니다'알고하지 않을 것입니다. 다른 언어 옵션이 있는지 모릅니다. –
'GenericComposite'이 템플릿이기 때문에 C++에서 이것을 할 수 있습니다 - 자바 제네릭과는 아주 다른 것입니다. –
dasblinkenlight