Feb 13

Almost in any application, even the simplest one, we’ll encounter a use for events. Events follow the Observer-Observable design pattern. However, how should this be implemented?

Clearly, the simplest solution is the following:



public interface MyEventListener {
  void performMyEvent(MyClass sender);
}

public class MyClass {
  private Collection<MyEventListener> listeners;

  public void addMyEventListener(MyEventListener l) {
    listeners.add(l);
  }

  public void removeMyEventListener(MyEventListener l) {
    listeners.remove(l);
  }

  protected void fireMyEvent() {
    for (MyEventListener l : listeners)
      l.performMyEvent(this);
  }
}

This way, listeners can implement the MyEventListener interface, and register/unregister themselves through the addMyEventListener and removeMyEventListener methods. MyClass will call fireMyEvent when it sees fit, and the listeners will perform their actions as needed.

Sounds great. But, what if inside one of the listeners’ performMyEvent method, it removes itself from being a listener by calling removeMyEventListener? An exception will be thrown, because the list was changed while being iterated!

A simple solution to this is adding a small map, to map the register/unregister requests done while the event is being fired:



public class MyClass {

  private Map<MyEventListener, Boolean> delayedListeners;
  private boolean isDelayed;

  public void addMyEventListener(MyEventListener l) {
    if (isDelayed) delayedListeners.put(l, true);
    else
      listeners.add(l);
  }

  // the remove method looks the same only places 'false' as the Boolean value

  protected void fireMyEvent() {
    isDelayed = true;

    for (MyEventListener l : listeners)
      l.performMyEvent(this);

    isDelayed = false;

    handleDelayed();
  }
}

This fix to the code makes it more robust. When an event is fired, the isDelayed flag (set to false in the class’ constructor) is set to true. This will ensure that any registration/unregistration will not really occur, but rather be stored for later handing in the delayedListeners map.

The delayedListeners is then handled by the handleDelayed method: The method will iterate through the values of the delayedListeners map and for every listener marked with true, it will add it to the list, while for every listener marked with false it will remove it from the list, effectively doing what the code calling to the original registartion/unregistration methods intended, but at a safer time.

Note that this implementation is not synchronized: Two threads might, in a certain circumstance, accidently cause an addition to the delayed listeners map while the event is past firing the event. This can be prevented by synchronizing the three methods to some arbitary object, which might as well be the delayed listeners map or listeners collection themselves.

I have implemented a small class which encapsulates the behaviour of listener collections as described above, having a simple interface for adding and removing listeners and firing events by using an calling interface specified at construction, and I will post its code later.

Share
Feb 11

I’ve read Egypt Java Experts’ post about generics tips and even though I agree with the author’s claim that the generics feature make for a better API design, sometimes it’s just an overkill for the framework you’re designing.

I will take hplusplus’ example AbstractProtocolFactory and HttpProtocolFactory and hope s/he won’t mind. These classes were declared as:


public abstract class AbstractProtocolFactory<P extends Protocol,
   C extends Configuration> { ... } 

public class HttpProtocolFactory extends
   AbstractProtocolFactory<HttpProtocol, HttpConfiguration> { ... }

Part of designing a good API, especially when talking about protocols and configurations, is to make it highly configurable in a post-deployment state. This is often done by using the Strategy design pattern, and can be seen in Java’s API in several occassions.

For example, if I used message digests, I would use create a MessageDigest instance using MessageDigest.getInstance(String), making sure that the String passed is retrieved from a configuration file, so I could change the digest type later.

Going back to hplusplus’ example, I couldn’t use such a thing. This is because the factory itself is generified, and in order to use it I need to provide the class types I require hard-coded. This might prove to be type-safer than using a string, but as I said before, some things need to be changed in a post-deployment state. If a year later I would decide to change the protocol type to an XML protocol instead of an HTTP protocol, I couldn’t without redeploying my application.

Another minor twist: In the example, hplusplus defines Protocol as:


public interface Protocol<C extends Configuration>

So a Protocol is defined to be used only with a certain type of Configuration. Because of this, the AbstractProtocolFactory could accidently be told to create a Protocol with a wrong type of Configuration, like HttpProtocol with XmlConfiguration. I would make a slight change like this:


public abstract class AbstractProtocolFactory<P extends Protocol<C>,
  C extends Configuration> { ... }

That way, it’s type-safeer.

Share
Jan 31

With the switch to Generics in Java 5.0, I wasn’t at all surprised to find Reference and ThreadLocal classes switched to a generified version where their get() methods return T. Code just looks better, so it makes sense to switch these wrapper class to generified versions.

But what happened to other wrapper classes, deeply rooted in Java as well? GuardedObject and SealedObject should have been generified as well! What makes them any different, aside from being in the security packages?

And if in these wrappers we discuss, I do believe some annotations for easier development using wrappers should have been made. I think the first thing I’ll do with the new annotations processing tool (JSR 269) is to create annotations that would hide the whole get() semantics, such as:



@WeakReference
public Object o;
..
..
// inside method
o = new Object();
..
..
Object i = o;
..
..

Would be compiled as if it was:


public WeakReference<Object> o;
..
..
o = new WeakReference(new Object());
..
..
i = o.get();
..
..

That’s nicer, isn’t it?

Share