注册监听器的正确位置在哪里
Where is the right place to register listeners
我正在做一个大量使用观察者模式的项目。
许多 classes 被用作 event/message 听众。
通常,监听 class 会在构造函数中注册自己,我发现有两个问题:
- 我们正在构造函数中工作
- class 变得依赖于观察到的 class,即使它只对事件本身感兴趣。
注册应该由听众负责class还是应该在其他地方?
从构造函数中进行订阅可能会导致继承问题。假设我们有这样的代码:
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 ...
}
...
}
Child
构造函数调用 Parent
构造函数,后者将自己注册到事件源。但是请注意,注册 Parent
时 Child
对象并未完成初始化。如果事件源在 Child
构造器完成之前更新,您的代码可能会表现得很奇怪。
避免此问题的一个简单方法是在工厂方法中进行订阅,隐藏 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 ...
}
...
}
我正在做一个大量使用观察者模式的项目。 许多 classes 被用作 event/message 听众。 通常,监听 class 会在构造函数中注册自己,我发现有两个问题:
- 我们正在构造函数中工作
- class 变得依赖于观察到的 class,即使它只对事件本身感兴趣。
注册应该由听众负责class还是应该在其他地方?
从构造函数中进行订阅可能会导致继承问题。假设我们有这样的代码:
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 ...
}
...
}
Child
构造函数调用 Parent
构造函数,后者将自己注册到事件源。但是请注意,注册 Parent
时 Child
对象并未完成初始化。如果事件源在 Child
构造器完成之前更新,您的代码可能会表现得很奇怪。
避免此问题的一个简单方法是在工厂方法中进行订阅,隐藏 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 ...
}
...
}