如何正确的使用Java事件通知(1)
分享于 点击 6614 次 点评:287
如何正确的使用Java事件通知(1)
通过实现观察者模式来提供 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 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 );
- }
- }
搞定了!要的就是这些。为了显得专(zhuang)业(bi)一点,我们可能还甚至为此实现了测试驱动,并为严密的代码覆盖率和那根表示测试通过的小绿条而洋洋自得。而且不管怎么样,这不就是我从网上那些教程里面学来的写法吗?
那么问题来了:这个解决办法是有缺陷的……
用户点评