2016-04-11 6 views
5

私はオブザーバーパターンを集中的に使用するプロジェクトに取り組んでいます。 多くのクラスがイベント/メッセージリスナーとして使用されます。 通常、リスニングクラスはコンストラクタで自身を登録し、私はこの2つの問題を参照してください。私たちは、コンストラクタ リスナーを登録する適切な場所はどこですか

  • で仕事をしている

    1. クラスは、それが唯一興味を持っていても観測されたクラスに依存するようになりますイベントそのもの。

    登録はリスニングクラスの責任であるべきですか、それとも他の場所にする必要がありますか?

  • +1

    私はコンストラクタが仕事をすることができますが、2はそれを分離する強い理由ではないと思います。リスナーがイベントにのみ関心がある(複数のイベントソースで再利用される可能性がある)場合は、他の誰かによって登録される必要があります。どのように正確にあなたのアプリケーションに依存するでしょう。 – Thomas

    答えて

    3

    コンストラクタ内からサブスクライブすると、継承の問題が発生する可能性があります。 Child CTORがイベントソースに自分自身を登録Parentのctorを呼び出し

    public class Parent { 
        public Parent(EventObject source) { 
         // initialize parent ... 
         source.subscribe(this::someMethod); 
        } 
        public void someMethod() { 
         ... 
        } 
    ... 
    } 
    
    public class Child extends Parent { 
        public Child(EventObject source) { 
         super(source); 
         // initialize child ... 
        } 
    ... 
    } 
    

    :私たちは、このようなコードを持っていると言います。ただしParentが登録されている場合、Childオブジェクトは初期化されません。 Child ctorが終了する前にイベントソースが更新されると、コードが非常に奇妙な動作をする可能性があります。

    この問題を回避する簡単な方法は、ファクトリメソッド内でサブスクリプションを作成し、ctorsを非表示にすることです。

    public class Parent { 
        public static Parent newInstance(EventObject source) { 
         Parent p = new Parent(); 
         source.subscribe(p::someMethod); 
         return p; 
        }   
        protected Parent() { 
         // initialize parent ... 
        } 
        public void someMethod() { 
         ... 
        } 
    ... 
    } 
    
    public class Child extends Parent { 
        public static Child newInstance(EventObject source) { 
         Child c = new Child(); 
         source.subscribe(c::someMethod); 
         return c; 
        }  
        protected Child() { 
         super(); 
         // initialize child ... 
        } 
    ... 
    } 
    
    関連する問題