欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

如何正确的使用Java事件通知(1)

来源: javaer 分享于  点击 6614 次 点评:287

如何正确的使用Java事件通知(1)


通过实现观察者模式来提供 Java 事件通知(Java event notification)似乎不是件什么难事儿,但这过程中也很容易就掉进一些陷阱。本文介绍了我自己在各种情形下,不小心制造的一些常见错误。

如何正确的使用Java事件通知

Java 事件通知

让我们从一个最简单的 Java Bean 开始,它叫StateHolder,里面封装了一个私有的 int 型属性 state 和常见的访问方法:

  1. public class StateHolder { 
  2.   private int state; 
  3.   
  4.   public int getState() { 
  5.     return state; 
  6.   } 
  7.   
  8.   public void setState( int state ) { 
  9.     this.state = state; 
  10.   } 

现在假设我们决定要 Java bean 给已注册的观察者广播一条 状态已改变 事件。小菜一碟!!!定义一个最简单的事件和监听器简直撸起袖子就来……

  1. // change event to broadcast 
  2.  
  3. public class StateEvent { 
  4.  
  5. public final int oldState; 
  6.  
  7. public final int newState; 
  8.  
  9. StateEvent( int oldState, int newState ) { 
  10.  
  11. this.oldState = oldState; 
  12.  
  13. this.newState = newState; 
  14.  
  15.  
  16.  
  17. // observer interface 
  18.  
  19. public interface StateListener { 
  20.  
  21. void stateChanged( StateEvent event ); 
  22.  

接下来,我们需要在 StateHolder 的实例里注册 StatListeners。

  1. public class StateHolder { 
  2.  
  3. private final Set listeners = new HashSet<>(); 
  4.  
  5. [...] 
  6.  
  7. public void addStateListener( StateListener listener ) { 
  8.  
  9. listeners.add( listener ); 
  10.  
  11.  
  12. public void removeStateListener( StateListener listener ) { 
  13.  
  14. listeners.remove( listener ); 
  15.  
  16.  

最后一个要点,需要调整一下StateHolder#setState这个方法,来确保每次状态有变时发出的通知,都代表这个状态真的相对于上次产生变化了:

  1. public void setState( int state ) { 
  2.  
  3. int oldState = this.state; 
  4.  
  5. this.state = state; 
  6.  
  7. if( oldState != state ) { 
  8.  
  9. broadcast( new StateEvent( oldState, state ) ); 
  10.  
  11.  
  12.  
  13. private void broadcast( StateEvent stateEvent ) { 
  14.  
  15. for( StateListener listener : listeners ) { 
  16.  
  17. listener.stateChanged( stateEvent ); 
  18.  
  19.  

搞定了!要的就是这些。为了显得专(zhuang)业(bi)一点,我们可能还甚至为此实现了测试驱动,并为严密的代码覆盖率和那根表示测试通过的小绿条而洋洋自得。而且不管怎么样,这不就是我从网上那些教程里面学来的写法吗?

那么问题来了:这个解决办法是有缺陷的……




相关栏目:

用户点评