Надоело каждый раз вызывать листенеры в цикле, придумал такую вещь:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
public class ListenerProxyHolder<T> implements InvocationHandler {
private final T proxyObject;
private final List<T> listeners = new ArrayList<T>();
public ListenerProxyHolder(Class<T> interfaceClass) {
proxyObject = (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[]{interfaceClass}, this);
}
public void addListener(T t) {
listeners.add(t);
}
public void removeListener(T t) {
listeners.remove(t);
}
public T getProxy() {
return proxyObject;
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
for (T listener : listeners) {
method.invoke(listener, objects);
}
return null;
}
}
Используется так:
public class Main {
private ListenerProxyHolder<Listener> proxyHolder = new ListenerProxyHolder<Listener>(Listener.class);
public Main() {
}
public void addListener(Listener listener) {
proxyHolder.addListener(listener);
}
public void removeListener(Listener listener) {
proxyHolder.removeListener(listener);
}
public void sum(int... args) {
int sum = 0;
for (int a : args) {
sum += a;
proxyHolder.getProxy().onResultReady(sum);
}
}
public static void main(String[] args) {
Main main = new Main();
main.addListener(new Listener() {
@Override
public void onResultReady(int result) {
System.out.println("Listener 1: " + result);
}
});
main.addListener(new Listener() {
@Override
public void onResultReady(int result) {
System.out.println("Listener 2: " + result);
}
});
main.sum(1, 2, 3);
}
private static interface Listener {
void onResultReady(int result);
}
}
Таким образом код прохода по всем листенерам находится в одном месте, а не раскидан по местам вызова. Причем вместо цикла, может быть и более сложный код, вроде отправки Runnable'а в EventLoop.
Так вообще принято делать, или java-way — это писать кучу однотипного кода руками?