我寫事件源模板我的課:事件來源:短道火災事件
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