13.6 Good and bad program


The good way to do it

To give you something to compare with, here's an example showing the recommended approach. By now it should be reasonably familiar and comfortable:

Case Study: GoodIdea.java

This is fairly trivial: each button has its own listener that prints something out to the console. But notice that there isn't an if statement in the entire program, or any statement that says, "I wonder what caused this event." Each piece of code is concerned with doing, not type-checking. This is the best way to write your code; not only is it easier to conceptualize, but much easier to read and maintain. Cutting and pasting to create new programs is also much easier.

Implementing the main class as a listener

The first bad idea is a common and recommended approach. This makes the main class (typically Applet or Frame, but it could be any class) implement the various listeners. Here's an example:

Case Study: BadIdea1.java

The use of this shows up in the three lines:

Since BadIdea1 implements ActionListener and WindowListener, these lines are certainly acceptable, and if you're still stuck in the mode of trying to make fewer classes to reduce server hits during applet loading, it seems to be a good idea. However:
  1. Java 1.1 supports JAR files so all your files can be placed in a single compressed JAR archive that requires only one server hit. You no longer need to reduce class count for Internet efficiency.
  2. The code above is much less modular so it's harder to grab and paste. Note that you must not only implement the various interfaces for your main class, but in actionPerformed( ) you've got to detect which action was performed using a cascaded if statement. Not only is this going backwards, away from the listener model, but you can't easily reuse the actionPerformed( ) method since it's specific to this particular application. Contrast this with GoodIdea.java, in which you can just grab one listener class and paste it in anywhere else with minimal fuss. Plus you can register multiple listener classes with a single event, allowing even more modularity in what each listener class does.

Mixing the approaches

The second bad idea is to mix the two approaches: use inner listener classes, but also implement one or more listener interfaces as part of the main class. This approach has appeared without explanation in books and documentation, and I can only assume that the authors thought they must use the different approaches for different purposes. But you don't in your programming you can probably use inner listener classes exclusively.

Case Study: BadIdea2.java

Since actionPerformed( ) is still tightly coupled to the main class, it's hard to reuse that code. It's also messier and less pleasant to read than the inner class approach. There's no reason that you have to use any of the old thinking for events in Java 1.1 -- so why do it?


Next Page