1

我受到AS3 中的 Signals 事件模式的启发,它取代了 flash 的原生事件。它在性能和可读性方面都做得更好。

所以我试图用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);
    }
}

这是警报管理器:

public class AlarmManager {

    public final AlarmEvent alarmEvent = new AlarmEvent();

    public void init(){
        // Dispatching the event
        alarmEvent.alarmEventHandler("Wake up");
    }

}

这是一个正在监听此事件的 Activity:

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);
    }
}

这就是我编写 Signal 类的方式

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);
    }
}

这种模式是:

  • 快速 - 无需搜索类型并触发 eventDispatcher,它立即完成。
  • 具有很好的可读性 - 只需查看类,您就可以确切地知道他发送了哪些事件,以及每个事件的外观。

但是,它运行得不好。如果我在接口中使用原语,则 Signal 无法找到方法并调用它。而且我不喜欢将方法名称传递给信号的想法。任何想法如何改善这一点?您如何看待这种模式?

4

1 回答 1

0

似乎这种模式已经在这些类中实现了

 java.util.Observable
 java.util.Observer
于 2012-10-26T14:41:07.073 回答