Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

The 'event generator' idiom

How and when to make a Java class observable

  • Print
  • Feedback

Page 5 of 5

  1. If there are vast differences in the frequency of events in a particular event category, consider defining separate listeners for high frequency and low frequency events. An example of this approach is illustrated by the MouseListener and MouseMotionListener interfaces of java.awt.event. Both of these listener interfaces define handler methods for MouseEvents. But because MouseEvents like "mouse moved" are generated so much more often than MouseEvents like "mouse pressed," the high frequency events like "mouse moved" get their own listener, MouseMotionListener. Lower frequency events like "mouse pressed" are handled by methods declared in plain old MouseListener.

  2. If your listeners need to cooperate with each other, consider making the event object mutable so that listeners can communicate to each other through the event object. An example of this variant is seen in the mutable AWTEvent class of java.awt, which is the superclass of all the AWT event classes defined in java.awt.event. Class AWTEvent includes two methods named consume() and isConsumed(), which enable listeners of AWT events to cooperate with one another. A listener can "consume" an event by invoking consume() on the event object. Subsequent listeners can determine that the event has already been consumed by invoking isConsumed() on the event object. If isConsumed() returns true (in other words, if another listener has already invoked consume() on the same event object), the listener can ignore the event.


Known uses
This idiom is based on the delegation-event model used by JavaBeans, the post-1.1 AWT, and Swing.

On Observer/Observable

As mentioned earlier in this article, the observer pattern shows up twice in the design of the Java API: once as the idiom described in this article (for JavaBeans, post-1.1 AWT, and Swing) and once in the Observer and Observable types of java.util. So, why don't I think the Observer/Observable types set a good example for a Java observer idiom?

It turns out that Observer/Observable classes more closely resemble the example code given in the Design Patterns book than they do the event generator idiom described in this article. In my opinion, however, these classes don't make the grade for the following reasons:

  1. Observable is a class you need to subclass to make an object observable. Thus, you have to find a way to fit Observable as a superclass in your observable class's single-inheritance hierarchy. This is often difficult.

  2. To turn a class into an observer (called a listener elsewhere in this article), you need only implement a single interface, Observer. The single method declared in the Observer interface, update(Observable, Object), is used to notify the observers. The Observer interface and update() method are generic so they can be used in just about any situation. Unfortunately, this generic design means that a programmer won't be able to easily understand code that uses Observer/Observable without digging into the nuts and bolts of the update handler methods. Contrast this with a listener that subclasses a MouseAdapter and overrides the mouseReleased() method. You already know a lot about the nature and source of the event just by looking at the names of the superclasses and methods, because they are more specific.

  3. One final reason I turned away from Observer/Observable is simply that using the event delegation model used in JavaBeans in non-bean classes eases any future transformation of a given class into a JavaBean. (Note that the AWT and Swing components, which use this event delegation model, are themselves JavaBeans.)


About JavaBeans

If you are at all familiar with JavaBeans, as you read this article you may have exclaimed, "Hey, this is all just JavaBeans stuff!" If you're thinking it would be better to just make every class a JavaBean, you would by definition use the "idiomatic" style in implementing the observer pattern to propagate JavaBeans events.

For those of you unfamiliar with JavaBeans, the minimum requirements for making a class a bean are simply that the class have a no-arg constructor and implement java.io.Serializable. Although a lengthy treatment of the question of whether or not to make a class a bean is beyond the scope of this article, I include a link to a transcript of an e-mail debate on just this topic in the Resources section. (The resource is titled "To Bean or Not To Bean.") Very briefly, my own opinion on this matter, quoted from the e-mail debate:

If someone is going to use a class in a bean builder, that class had better be a bean. Otherwise, you needn't force it into a bean, though it may be bean-ready by its very nature. I do, however, think you should use the bean/Java naming conventions and JDK1.1 event model scheme regardless of whether your class has a no-arg constructor or implements Serializable.


For the full discussion of the proper time and place to make classes into beans (and a broader array of opinions) check out the "To Bean or Not To Bean" e-mail debate.

In the telephone example above, class Telephone is not a JavaBean, because it doesn't implement java.io.Serializable. I would venture to say that you probably should have Telephone implement Serializable, unless you have a specific reason for not doing so. That way, if client programmers ever want to serialize an instance of the class, their lives will be made easier. In this case, while Telephone isn't a JavaBean, its design benefits from the JavaBeans event delegation model.

Conclusion

In my world view, the two main benefits of idioms, such as the event generator idiom described in this article, are:

  1. Idioms, like patterns, establish a vocabulary for discussing design and serve as an effective way for less experienced programmers to benefit from the hard knocks of more experienced programmers.

  2. Code that uses idioms is easier to understand, use, and change (for those programmers familiar with the idioms).


The event generator idiom allows one or more listener objects to be notified of state changes or events provided by an event generator. The number and type of listeners may be unknown at compile-time, and can vary throughout the course of execution. The loose coupling of listeners and event generators make the code easier to change or reuse in changing situations.

Next month

In next month's Design Techniques, I'll continue the series of articles that focus on designing classes and objects. Next month's article will describe several basic object idioms.

A request for reader participation

I encourage your comments, criticisms, suggestions, flames -- all kinds of feedback -- about the material presented in this column. If you disagree with something, or have something to add, please let me know.

You can either participate in a discussion forum devoted to this material, enter a comment via the form at the bottom of the article, or e-mail me directly using the link provided in my bio below.

About the author

Bill Venners has been writing software professionally for 12 years. Based in Silicon Valley, he provides software consulting and training services under the name Artima Software Company. Over the years he has developed software for the consumer electronics, education, semiconductor, and life insurance industries. He has programmed in many languages on many platforms: assembly language on various microprocessors, C on Unix, C++ on Windows, Java on the Web. He is author of the book: Inside the Java Virtual Machine, published by McGraw-Hill.

Read more about Core Java in JavaWorld's Core Java section.

  • Print
  • Feedback

Resources
  • Bill's next book is Flexible Java http://www.artima.com/flexiblejava/index.html
  • The discussion forum on event generators can be found at http://www.artima.com/flexiblejava/fjf/eventgen/index.html
  • Links to all previous Design Techniques articles http://www.artima.com/designtechniques/index.html
  • A description of the "I shall return" idiom, which describes a way to return multiple values from a Java method http://www.artima.com/flexiblejava/ishallreturn.html
  • Recommended books on Java design, including information on the Gang of Four's Design Patterns book http://www.artima.com/designtechniques/booklist.html
  • A transcript of an e-mail debate between Bill Venners, Mark Johnson (JavaWorld's JavaBeans columnist), and Mark Balbe on whether or not all objects should be made into beans http://www.artima.com/flexiblejava/comments/beandebate.html
  • Source packet that contains the example code used in this article http://www.artima.com/flexiblejava/code.html
  • A nice page that describes UML. http://www.holub.com/goodies/oo_design/uml.html
  • Object orientation FAQ http://www.cyberdyne-object-sys.com/oofaq/
  • 7237 Links on Object Orientation http://www.rhein-neckar.de/~cetus/software.html
  • The Object-Oriented Page http://www.well.com/user/ritchie/oo.html
  • Collection of information on OO approach http://arkhp1.kek.jp:80/managers/computing/activities/OO_CollectInfor/OO_CollectInfo.html
  • Design Patterns Home Page http://hillside.net/patterns/patterns.html
  • A Comparison of OOA and OOD Methods http://www.iconcomp.com/papers/comp/comp_1.html
  • Object-Oriented Analysis and Design MethodsA Comparative Review http://wwwis.cs.utwente.nl:8080/dmrg/OODOC/oodoc/oo.html
  • Patterns discussion FAQ http://gee.cs.oswego.edu/dl/pd-FAQ/pd-FAQ.html
  • Patterns in Java AWT http://mordor.cs.hut.fi/tik-76.278/group6/awtpat.html
  • Software Technology's Design Patterns Page http://www.sw-technologies.com/dpattern/
  • Previous Design Techniques columns http://www.javaworld.com/topicalindex/jw-ti-techniques.html