我受到Signals events pattern in AS3的啓發,它取代了閃存的本地事件。而且在性能和可讀性方面都表現更好。Java - 信號事件模式
所以我想在Java中實現它。
這種模式的主要思想是,你正在使用對象而不是類型,通過這個時間來找到「Dispatcher」類來處理你的事件分派(調度事件正在向所有的監聽者發送事件)
因此讓我們跳到代碼: 在這個例子中,我將創建AlarmManager並處理他的報警事件。
首先,我們需要建立我們的接口爲這個事件
public interface IAlarmEvent {
void alarmEventHandler(String alert);
}
現在事件本身:
public class AlarmEvent extends Signal<IAlarmEvent> implements IAlarmEvent {
public void alarmEventHandler(String alert) {
dispatch("alarmEventHandler", alert);
}
}
這裏是AlarmManger:
public class AlarmManager {
public final AlarmEvent alarmEvent = new AlarmEvent();
public void init(){
// Dispatching the event
alarmEvent.alarmEventHandler("Wake up");
}
}
這裏是一個活動誰在聽這個事件:
public class MainActivity extends Activity implements IAlarmEvent{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AlarmManager alarmManager = new AlarmManager();
alarmManager.alarmEvent.addListener(this);
alarmManager.init();
}
public void alarmEventHandler(String alert) {
Log.d("MyLog", "Event : " + alert);
}
}
這裏是我如何寫作信號類
public abstract class Signal<T> {
private LinkedHashMap<T, T> listeners = new LinkedHashMap<T, T>();
protected void dispatch(String methodName, Object...arguments){
Set<T> keySet = listeners.keySet();
if(keySet.size() == 0){
return;
}
Iterator<T> iterator = keySet.iterator();
Method method = null;
do{
T listener = iterator.next();
if(method == null){
try {
Class<?>[] classes = new Class<?>[arguments.length];
for(int i = 0; i < arguments.length; i++){
classes[i] = arguments[i].getClass();
}
method = listener.getClass().getMethod(methodName, classes);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
try {
method.invoke(listener, arguments);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}while(iterator.hasNext());
}
public void addListener(T listener) {
listeners.put(listener, listener);
}
public void removeListener(T listener) {
listeners.remove(listener);
}
}
這種模式是:
- 快 - 無需搜索類型,並觸發此事件,它立即進行。
- 具有很好的可讀性 - 僅僅通過查看課程,您就可以確切瞭解他發送的事件以及每個事件的外觀。
然而,它不工作。如果我爲我的接口使用原語,則Signal無法找到該方法並調用它。我不喜歡將方法名稱傳遞給信號的想法。任何想法如何改善這一點?你對這種模式有什麼看法?
只是一個供參考已經執行:'設置的keySet = listeners.keySet(); (keySet == null || keySet.size()== 0){ return; } keySet永遠不會爲空 –
bgs
@BGS ok我修正了它 –
我在哪裏可以找到你的代碼以便使用它(請獲得一些github回購?)?我也喜歡as3信號。謝謝。 – SudoPlz