2016-04-11 55 views
5

Sto lavorando a un progetto che utilizza intensamente il modello di osservatore. Molte classi sono utilizzate come ascoltatori di eventi/messaggi. Di solito, la classe di ascolto si registra nel costruttore, e vedo una due problemi con questo:Dov'è il posto giusto per registrare gli ascoltatori

  1. Stiamo facendo il lavoro nel costruttore
  2. La classe diventa dipendente dalla classe osservata anche se è solo interessato nel caso stesso.

la registrazione dovrebbe essere la responsabilità del corso di ascolto o dovrebbe essere un altro posto?

+1

Direi che un costruttore può funzionare ma 2 non è un motivo valido per separarlo. Se gli ascoltatori sono interessati solo agli eventi (e potrebbero potenzialmente essere riutilizzati su più fonti di eventi) dovrebbero essere registrati da qualcun altro. Dove e in che modo esattamente dipenderà dalla tua applicazione. – Thomas

risposta

3

La sottoscrizione all'interno di un costruttore può causare problemi di ereditarietà. Supponiamo di avere il codice che assomiglia a questo:

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 ... 
    } 
... 
} 

Il Child ctor chiama il Parent ctor, che si registra per l'origine evento. Si noti tuttavia che l'oggetto Child non viene inizializzato quando è registrato lo Parent. Se la fonte degli eventi si aggiorna prima che il codice Child sia terminato, il codice potrebbe comportarsi in modo molto strano.

Un modo semplice per evitare questo problema consiste nell'effettuare abbonamenti all'interno dei metodi di fabbrica, mantenendo nascosti i vettori.

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 ... 
    } 
... 
} 
Problemi correlati