1

フラッシュのネイティブ イベントを置き換えるAS3 の Signals イベント パターンに触発されました。そして、パフォーマンスと読みやすさの両方で、はるかに優れています。

だから私はそれを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);
    }
}

そして、これが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 をトリガーする必要はありません。すぐに完了します。
  • 読みやすさ - クラスを見るだけで、彼がディスパッチするイベントと、各イベントがどのように見えるかを正確に知ることができます。

しかし、うまくいきません。インターフェイスにプリミティブを使用している場合、シグナルはメソッドを見つけて呼び出すことができません。そして、メソッド名をシグナルに渡すという考えは好きではありません。これを改善する方法はありますか?そして、このパターンについてどう思いますか?

4

1 に答える 1

0

このパターンはすでにこれらのクラスに実装されているようです

 java.util.Observable
 java.util.Observer
于 2012-10-26T14:41:07.073 に答える