通过实现观察者模式来提供 Java 事件通知(Java event notification)似乎不是件什么难事儿,但这过程中也很容易就掉进一些陷阱。本文介绍了我自己在各种情形下,不小心制造的一些常见错误。
Java 事件通知
让我们从一个最简单的 Java Bean 开始,它叫StateHolder,里面封装了一个私有的 int 型属性 state 和常见的访问方法:
public class StateHolder {
private int state;
public int getState() {
return state;
}
public void setState( int state ) {
this.state = state;
}
}
现在假设我们决定要 Java bean 给已注册的观察者广播一条 状态已改变 事件。小菜一碟!!!定义一个最简单的事件和监听器简直撸起袖子就来……
// change event to broadcast
public class StateEvent {
public final int oldState;
public final int newState;
StateEvent( int oldState, int newState ) {
this.oldState = oldState;
this.newState = newState;
}
}
// observer interface
public interface StateListener {
void stateChanged( StateEvent event );
}
接下来,我们需要在 StateHolder 的实例里注册 StatListeners。
public class StateHolder {
private final Set<StateListener> listeners = new HashSet<>();
[...]
public void addStateListener( StateListener listener ) {
listeners.add( listener );
}
public void removeStateListener( StateListener listener ) {
listeners.remove( listener );
}
}
最后一个要点,需要调整一下StateHolder#setState这个方法,来确保每次状态有变时发出的通知,都代表这个状态真的相对于上次产生变化了:
public void setState( int state ) {
int oldState = this.state;
this.state = state;
if( oldState != state ) {
broadcast( new StateEvent( oldState, state ) );
}
}
private void broadcast( StateEvent stateEvent ) {
for( StateListener listener : listeners ) {
listener.stateChanged( stateEvent );
}
}