How to correctly use Java Event Notifications (1)
It seems that implementing the observer mode to provide Java event notification is not difficult, but it is also easy to fall into some traps. This article describes some common mistakes that I accidentally made in various situations.
Java Event Notification
Let's start with the simplest Java Bean called StateHolder, which encapsulates a private int-type attribute state and common access methods:
- public class StateHolder {
- private int state;
-
- public int getState() {
- return state;
- }
-
- public void setState( int state ) {
- this.state = state;
- }
- }
Now let's assume that we want Java bean to broadcast a state change event to the registered observer. A piece of cake !!! Define the simplest event and listener. Just pull up your sleeves ......
- // 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 );
-
- }
Next, we need to register StatListeners in the StateHolder instance.
- 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 );
-
- }
-
- }
The last key point is to adjust the StateHolder # setState method to make sure that the notification is sent when the status changes each time, it means that the status has actually changed from the previous one:
- 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 );
-
- }
-
- }
Done! That's all you need. In order to look like a professional (zhuang) Industry (bi), we may have even implemented a test drive for this purpose, it is self-satisfied with the strict code coverage rate and the small green bars that indicate passing the test. And no matter what, isn't that what I learned from those online tutorials?
The problem arises: This solution is flawed ......