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