Patterns and Java - A Matter of Good Taste
Serialization is the measure of choice to make objects persistent, or to exchange objects between different processes (e.g., over a network). It is the backbone Java mechanism to implement patterns like PROTOTYPE (which requires some kind of a persistent object repository), or PROXY applications (like RMI, where we need to shuffle objects between the server and the client in a architecture-neutral way).
Java promotes patterns even outside its own domain.
Many pattern definitions completely ignore concurrency, but Java is meant to be used threaded. Concurrency constructs therefore should integrate seamlessly. They should require as few additional objects and protocols as possible, so that we don't end up with threaded and non-threaded variants of the same patterns.
Synchronized methods and blocks (as the visible part of object monitors) are a handy construct to ensure exclusiveness. In fact, it is so handy that people often think it's sufficient to turn all methods of a class into synchronized ones, in order to ensure thread safety. Well, it might be "safe," but sometimes in a very deadlocked way. The idiom of choice is to synchronize only local operations, but then we really can get along with it for threaded versions of patterns like SINGLETON or OBSERVER (leave alone registry modifications during notification).
The Wait and Notify mechanism has to be used if patterns need inter-object synchronization, or maybe even high-level synchronization objects, like semaphores.
Final field and parameter attributes seem to be just a minor aspect, but they actually can have an impact on patterns dealing with concurrency: since they can't change, access to final values doesn't have to be synchronized.
To see some of the above features and idioms in action, look at this:
Listing 1. An extended example of the Future pattern from [Lea99].
Up to the libraries
With all the supporting mechanisms mentioned above, it is no surprise that we find patterns in almost all Java class libraries. Here are some examples of the kernel API:
- the combination of the (system domain) java.lang.Thread.start() and the (application domain) Runnable.run() is a STRATEGY example.
- java.io.FilterInputStream is a DECORATOR for InputStreams
- java.net.URLStreamHandlerFactory is a ABSTRACT FACTORY
- java.util.Enumeration, java.util.Iterator and its implementors are ITERATOR examples
- java.util.Observable and java.util.Observer are a OBSERVER implementation.
RMI, of course, utilizes a PROXY pattern (among others). Due to the nature of GUIs (graphical user interfaces), most patterns can be found in the AWT (Abstract Windowing Toolkit) and its related libraries. This is only a brief list of the most obvious patterns:
- java.awt.Toolkit is an ABSTRACT FACTORY for peer objects, it's instance is a SINGLETON
- java.awt.Component.getGraphics() and Toolkit.getImage() are FACTORY METHODS
- java.awt.Container and java.awt.Component are a COMPOSITE example
- java.awt.LayoutManager is a STRATEGY implementation for geometry handling
- the old java.awt.Event-based event handling is a CHAIN OF RESPONSIBILITY variant
- the new java.awt.AWTEvent, the java.awt.event.EventListener interface, and the java.awt.AWTEventMulticaster form a TYPEDMESSAGE pattern (a type-safe OBSERVER variant).
Of course, pattern examples aren't restricted to the standard libraries. You can find them in many of the more-complex Java applications and third-party libraries, which indicates that most Java programmers got the message from Java's inventors.
In some sense, we could even think of an applet as a COMMAND object, with the browser acting as an Invoker. This is certainly beyond the scope of the original design pattern, but it follows the same principle and shows us that Java promotes patterns even outside its own domain.
There is not yet "the" standard book about patterns and Java, and no Java-dedicated pattern repository. However, a lot of Java-related information can be found at these sites:
The following books provide a whole wealth of knowledge about patterns in general, specialized patterns, and Java idioms:
[GoF95] E. Gamma, R. Helm, R. Johnson, and J. Vlissides
Design Patterns Elements of Reusable Object-Oriented Software,
Addison-Wesley, Reading, MA, 1995
This is the "dragon book" of design patterns. Almost everyone refers to it, so you should read it first.
[BMR+96] F. Buschmann, H. Rohnert, and R. Meunier
Pattern Oriented Software Architecture A System of Patterns
Wiley, Chichester, 1996
This book examines patterns in a more-general software engineering context. It puts more emphasis on pattern classification than [GoF95].
[V98] J. Vlissides
Pattern Hatching Design Patterns Applied
Addison-Wesley, Reading, MA, 1998
Having read the first two books, this is a very interesting reflection on how to identify, refine, and use design patterns.
[Lea99] D. Lea
Concurrent Programming in Java: Design Principles and Patterns, Second Edition
Addison-Wesley, Reading, MA, 1999
[WB99] N. Warren and P. Bishop
Java In Practice: Design Styles and Idioms for Effective Java
Addison-Wesley, Reading, MA, 1999
[La99] J. Langr
Essential Java Style: Patterns for Implementation
Prentice Hall, New York, 1999
[Gr98] M. Grand
Patterns in Java: A Catalog of Reusable Design Patterns Illustrated with UML, Volume 1
John Wiley & Sons, New York, 1998
Patterns in Java, Volume 2
John Wiley & Sons, New York, 1999
A short intro for design patterns can be found in part one of this article
About the author
Peter Mehlitz is co-founder of Transvirtual Technologies. He designed and implemented the AWT libraries of Kaffe. Prior to that, he worked as a technical lead for BISS GmbH, developing systems like the BSA C++-framework, the CThrough development environment, and the BISS-AWT Java libraries. Peter has about 20 years of experience in software development, using about a dozen different programming languages, with a strong focus on design issues and large, object-oriented frameworks (written in C++, Smalltalk, and Java). He holds an M.S. in aerospace engineering from the university of the German armed forces, Munich.
Page 2 of 3