我写事件源模板我的课:事件来源:短道火灾事件
public class EventSource<E> {
protected ArrayList<E> listeners = new ArrayList<E>();
public void addListener(E listener)
{
listeners.add(listener);
}
public void removeListener(E listener)
{
listeners.remove(listener);
}
}
触发事件我需要调用是这样的:
for(SomeListener listener: listeners)
listener.onSomeEvent();
这看起来相当丑陋的事件发生。有没有一种方法来调用一些短这样的:
fire(SomeListener.onSomeEvent)
或
fire(onSomeEvent)
?
我已经找到3个解决方案:
我使用Java反射和传递方法的名称作为参数传递给在模板中的一些方法,这将调用此方法对所有的听众。但是我认为它是低效的,因为需要解析字符串(方法名称)。以及如何以不丑的方式传递参数 - 问题依然存在。
II使用的所有方法的名称相同,但通过不同的参数:
public struct SomeEvent1
{
int someData;
}
public struct SomeEvent2
{
int someAnotherData;
double probablyMoreData;
}
public interface SomeListener
{
public void fire(SomeEvent1 e);
public void fire(SomeEvent2 e);
}
但是,它需要建立这个事件结构,即使我不需要任何参数。
III使用授权。想象一下,SomeEventSource扩展了EventSource。现在,我可以调用onSomeEventI(),因为我写了一首歌SomeEventSource这些方法:
public void onSomeEventI()
{
for(SomeListener listener: listeners)
listener.onSomeEventI();
}
但我不能写在通用EventSource的那些方法,因为它是监听器无关。在SomeEventSource中编写这些方法使通用的EventSource比无用的更加无用。
问题依然存在:如何在短时间内引发事件?
嗯......使用泛型确实不适用于通用事件处理。看看Java的Java类Observer和Observable。他们不是最好的,但也许你可以接管一些零件。 – Seelenvirtuose
是的,Observer - Observerable比写自己的东西好。但它与方法(II)具有相同的缺点。如果有某种东西像std :: bind(我来自C++)绑定到一个函数并将其作为参数传递。 – Deepscorn
Java 8? Lambda表达式? – Seelenvirtuose