Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Clever Facade makes JDBC look easy

The Facade design pattern lets you focus on the big picture rather than becoming mired in the details of JDBC

Before I dive into this second installment of my new Cool Tools column, allow me to offer up some corrections and clarifications to last month's column, "How to easily reconfigure your applications -- while they're running." I received lots of feedback on that article, most of it constructive, some of it abusive, but if it makes me a better writer and/or programmer, it's all welcome. (Although, I do prefer the polite messages over the vulgar ones.)

Static finals and compilers

Last month I discussed the scenario wherein the values of static final variables are being compiled into the classes that reference them, thus requiring a recompile of the entire project for any changes to propagate. I stated that this behavior is (or was two years ago) different from one compiler to the next. JavaWorld reader Ethan Nicholas was kind enough to correct me on the matter:



This behavior is specified by the Java Language Specification, section 13.4.8. The gist of it is that references to primitive constant fields (static final with a constant primitive initializer) are compiled into other classes by value rather than by reference. What you probably saw was a constant number refusing to change, even though you were accustomed to constant strings changing -- this is correct behavior (according to the spec), as strings are not primitive and so must be passed by reference. It certainly should not vary from compiler to compiler -- if a compiler compiles a reference to a primitive constant, rather than just the value, it is in error.



The singleton

A few of you commented to me that I should have made the GlobalValues object into a singleton. The term singleton comes from the realm of design patterns. A singleton object strives to ensure that it exists in only one instance and that it offers a global point of access.

In essence, the GlobalValues object is a singleton. All of the tool's methods are static, and the internal Hashtable is static, so you can (and should) reference the tool via the class name. I demonstrated this in my article, and that is how I intended the tool to be used. As some of you pointed out, however, I can go a couple steps further to make GlobalValues a singleton in the purest sense.

First of all, I should have declared the class to be final, as in:


public final class GlobalValues


This ensures that nobody can subclass the GlobalValues and override the functionality. A nice safeguard.

Second, I should have declared a private constructor:


private GlobalValues(){}


This ensures that no one can create instances of the object. At first, having numerous instances doesn't seem all that troublesome because the internal Hashtable is static, which means all of the instances would share the same data. There is a nasty race condition, however: a static synchronized method does not synchronize across multiple instances of its class. For further reading on this, see Part 7 of Allen Holub's Java Toolbox series, "Programming Java threads in the real world."

The Factory

A couple of you also suggested that I make the tool serializable and thus RMI-friendly. I don't see the practicality of this, but it certainly can be done. The first thing I need to do is make all the internal data nonstatic. In the case of GlobalValues, the internal data is the lonely Hashtable. Once the internal data is nonstatic, it doesn't make any sense for the get() method to be static. We must now instantiate the tool in order to use it -- thus, the Value inner class doesn't need to be static either. Also, the JDBC driver loading block should be moved out of the static block and into the private constructor. Now, nothing in GlobalValues is static.

1 | 2 | 3 | 4 | 5 | 6 |  Next >
Resources
  • The complete source code for this article is available at http://www.javaworld.com/jw-05-1999/cooltools/jw-05-cooltools.zip
  • Sun's JDBC home page http://java.sun.com/products/jdbc/
  • Design patterns home page http://hillside.net/patterns/patterns.html
  • The Open Source Page http://www.opensource.org/
  • Free Software Foundation and the GNU Project http://www.fsf.org/
  • Thomas's previous articles in JavaWorld
  • "Build your own ObjectPool in Java to boost app speed" (June 1998) Thomas's example object pool design shows you how to employ object pooling to boost performance and minimize memory use http://www.javaworld.com/jw-06-1998/jw-06-object-pool.html
  • "Improve the robustness and performance of your ObjectPool" (August 1998) Thomas shows you how to enhance his example pooling utility to include exception propagation and the cleanup thread http://www.javaworld.com/jw-08-1998/jw-08-object-pool.html
  • "Cool ToolsHow to easily reconfigure your applications -- while they're running" (April 1999) The Cool Tools column debuts with an introduction to the concept of dynamic configuration http://www.javaworld.com/jw-04-1999/jw-04-cooltools.html