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

Java Tip 68: Learn how to implement the Command pattern in Java

Add flexibility and extensibility to your programs with this object-oriented equivalent of the callback

  • Print
  • Feedback
Design patterns not only accelerate the design phase of an object-oriented (OO) project but also increase the productivity of the development team and quality of the software. A Command pattern is an object behavioral pattern that allows us to achieve complete decoupling between the sender and the receiver. (A sender is an object that invokes an operation, and a receiver is an object that receives the request to execute a certain operation. With decoupling, the sender has no knowledge of the Receiver's interface.) The term request here refers to the command that is to be executed. The Command pattern also allows us to vary when and how a request is fulfilled. Therefore, a Command pattern provides us flexibility as well as extensibility.

In programming languages like C, function pointers are used to eliminate giant switch statements. (See "Java Tip 30: Polymorphism and Java" for a more detailed description.) Since Java doesn't have function pointers, we can use the Command pattern to implement callbacks. You'll see this in action in the first code example below, called TestCommand.java.

Developers accustomed to using function pointers in another language might be tempted to use the Method objects of the Reflection API in the same way. For example, in his article "Java Reflection," Paul Tremblett shows you how to use Reflection to implement transactions without using switch statements. I've resisted this temptation, since Sun advises against using the Reflection API when other tools more natural to the Java programming language will suffice. (See Resources for links to Tremblett's article and for Sun's Reflection tutorial page.) Your program will be easier to debug and maintain if you don't use Method objects. Instead, you should define an interface and implement it in the classes that perform the needed action.

Therefore, I suggest you use the Command pattern combined with Java's dynamic loading and binding mechanism to implement function pointers. (For details on Java's dynamic loading and binding mechanism, see James Gosling and Henry McGilton's "The Java Language Environment -- A White Paper," listed in Resources.)

By following the above suggestion, we exploit the polymorphism provided by the application of a Command pattern to eliminate giant switch statements, resulting in extensible systems. We also exploit Java's unique dynamic loading and binding mechanisms to build a dynamic and dynamically extensible system. This is illustrated in the second code sample example below, called TestTransactionCommand.java.

The Command pattern turns the request itself into an object. This object can be stored and passed around like other objects. The key to this pattern is a Command interface, which declares an interface for executing operations. In its simplest form, this interface includes an abstract execute operation. Each concrete Command class specifies a receiver-action pair by storing the Receiver as an instance variable. It provides different implementations of the execute() method to invoke the request. The Receiver has the knowledge required to carry out the request.

  • Print
  • Feedback

Resources
  • Design Patterns by Gamma, Helm, Johnson, Vlissides, Addison-Wesley, 1994, ISBN 0-201-63361-2 http://www.bookbuyer.com/cgi-bin/getTitle.cgi?ISBN=0201633612
  • Dr. Dobb's Journal, January 1998"Java ReflectionNot just for tool developers," by Paul Tremblett http://www.ddj.com/articles/1998/9801/9801c/9801c.htm
  • Sun's Reflection page http://java.sun.com/docs/books/tutorial/reflect/index.html
  • "The Java Language Environment -- A White Paper" (May 1996), by James Gosling and Henry McGilton covers details about Java's dynamic loading and binding mechanism http://java.sun.com/docs/white/langenv/
  • For more on taking advantage of Java's unique feature of dynamic loading and binding mechanism to build a dynamic and dynamically-extensible system, see http://java.sun.com/docs/white/langenv/