通过实现观察者模式来提供 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 );
  }
  }