2011-07-07 14 views
3

オブザーバに複数のタイプのイベントを通知する必要があるオブザーバブルのupdate()コールを解釈する際に起こる醜い条件付きキャスティングを回避しようとしています。また、notifyObservers()/ update()メソッドにフラグを渡さないことをお勧めします。私はオブザーバーが変わったのかを調べるために観察可能なオブジェクトをポーリングする必要がありますする必要はありません1つのオブザーバブルに対して複数の観測可能なイベント

、私は、この新しいデータは、update()メソッドを経由して観測者に与えられるしたい(または同様。)

私は解決策を考えています。私は通知の種類ごとに1つの観察可能なオブジェクトをインスタンス化します。観察可能なハードウェアデバイスを表すオブジェクトである、それはその状態を表す観測含まれています:例えばこの方法で

public final Observable connectionState = new Observable(); 
public final Observable dataState = new Observable(); 

を、オブザーバーは1人のオブザーバーとして、クエリや条件鋳造の任意の並べ替えをする必要はありません、つまり、通知タイプごとに1つのオーバーライドされたupdate()メソッドを使用できます。

これは私が考えることができる最もエレガントな解決策ですが、Observers/Observablesを正しく使用する方法についてのポイントを忘れてしまったというこの恐ろしい感情があります。その解決策と

私の主な問題点は以下のとおりです。

  1. は、それはまだ観測が観察する必要があるため、彼らは公共のメンバーでなければなりません(少なくとも、それは条件付きではありません)
  2. キャストを必要とします。オブザーバーはaddObservable()を呼び出すことができますが、notifyObservers()も呼び出すことができます。

私は正しいことをしていますか?

おかげ

答えて

3

あなたはObserverパターンのJavaの1.0実装の制限に苦労しています。質問this answerを見てくださいどこでも使用されているjava.util.Observableですか?

その デザインは欠陥があるので、彼らは、使用されていない。彼らは 安全を入力されていません。 がObservableをObservableに実装しているオブジェクトを添付することができます。 これは微妙なバグが発生する可能性があります。 型安全 インターフェイス内部それらをラッピング

が最初からパターンを実装するよう 作業のほぼ同じ量であるので、私は後者が多くの場合において好ましい ある推測します。

あなたの要件をjava.util.Observerに入れようとするのではなく、必要に応じて独自のバージョンのパターンを実装してください。

3

あなたはVisitorパターンと一緒にペア観測を使用しようとすることができます:

class MyObserver implements Observer, EventVisitor { 
    public void update(Observable o, Object arg) { 
     ((EventAcceptor) arg).accept(this); 
    } 

    public void visit(SomeEvent v) { 
     System.out.println("SomeEvent: " + v.s); 
    } 

    public void visit(AnotherEvent v) { 
     System.out.println("AnotherEvent: " + v.info); 
    } 
} 

interface EventVisitor { 
    void visit(SomeEvent v); 
    void visit(AnotherEvent v); 
} 

interface EventAcceptor { 
    void accept(EventVisitor v); 
} 

class SomeEvent implements EventAcceptor { 
    public final String s; 

    public SomeEvent(String s) { 
     this.s = s; 
    } 

    public void accept(EventVisitor v) { 
     v.visit(this); 
    } 
} 

class AnotherEvent implements EventAcceptor { 
    public final String info; 

    public AnotherEvent(String info) { 
     this.info = info; 
    } 

    public void accept(EventVisitor v) { 
     v.visit(this); 
    } 
} 

class MyObservable extends Observable { 
    void handleSomeEvent() { 
     setChanged(); 
     notifyObservers(new SomeEvent("some event")); 
    } 

    void handleAnotherEvent() { 
     setChanged(); 
     notifyObservers(new AnotherEvent("some event")); 
    } 
} 

class Sample { 
     public static void main(String[] args) { 
      MyObservable observable = new MyObservable(); 
      observable.addObserver(new MyObserver()); 
      observable.handleSomeEvent(); 
      observable.handleAnotherEvent(); 
     } 
} 
0

は、あなたの問題の可能な解決策がたくさんあります。 Observableクラスがあなたの問題に適していないと感じる場合は、独自のリスナーのコレクションを維持することができます。

interface Listener { 
    void onEvent1(Type1 arg); 
    void onEvent2(Type2 t2, Type3 t3); 
    void onEvent3(); 
} 

List<Listener> listeners = new CopyOnWriteArray<Listener>(); 

public void addListener(Listener l) { listeners.add(l); } 

public void onEvent1(Type1 arg) { 
    for(Listener l: listeners) l.onEvent1(arg); 
} 
関連する問題