The Importance of Messaging
When you think of two software components communicating, you usually think in terms of one object invoking a method on another object. You can, however, think of a method invocation as one object sending a message to another. For instance, when you call getName on a Person object, you are sending a message to the Person saying "Hey! Tell me who you are!" In general, system designers like to think in terms of messages between objects-method calls are just one way to implement messages.
Method invocations work well on a small scale, and they are useful even for a distributed system. As you deal with larger systems, method calls (both local and remote) start to cause problems. Many times you need to connect two components that have totally different concepts of time. One system might be an interactive GUI application that requires immediate responses, whereas the other might be a large, batch-oriented system that processes huge groups of records at scheduled times.
When your GUI application sends data to the batch system, you don't want to sit there waiting for a response-especially if it might be an hour before you get one. You want to send your data to the batch system and go about your business. You really just need to send a message to the batch system telling it to process your data when it gets a chance.
Messaging is such a popular way to connect system components that an entire industry is devoted to Message-Oriented Middleware (MOM). One of the big attractions of messaging is that the coupling between the client and the server is much looser. As Figure 19.1 shows, components that interact with method calls have a tighter coupling and are more time- sensitive.
Figure 19.1. Messaging creates a loose coupling between components.
Messaging has a lot of things going for it. First, it is reasonably language- and operating system independent. A Java program on a PC can send a message to a COBOL program running on a mainframe. Although you get some of these cross-platform and cross-language benefits from CORBA, it's easier to write an interface to a messaging system than it is to make a CORBA language binding.
Don't get the impression that messages are the ideal way to do everything. Some of the advantages of messages are also disadvantages. It doesn't make sense to use messages between local Java classes when method calls satisfy your requirements. Messages are typically unidirectional; that is, they are like one-way message calls. To emulate the functionality of a method call, you must also send a reply message back to the original sender. When you start dealing with request and response messages, you encounter sequencing issues. What happens if you send getFirstName and getLastName messages to a Person and get Curtis and Anthony back? Is the person's name Curtis Anthony or Anthony Curtis? Unless you assign some sort of identifier to match the response to the request, you have no way of knowing. If you invoke getFirstName and getLastName as methods, however, you know which name goes with which method call.
Consider, too, that methods allow you to throw exceptions and also synchronize against simultaneous access. These are things that are possible with messaging, but require extra work.
So, when do you use messaging and when do you use method calls? Sometimes it's a tough decision. For communications between Java classes that always run inside the same program-that is, for non-network communications, method calls are almost always your best bet.
If one component does its processing on a different time scale than another (for example, one requires immediate response, whereas the other takes a long time to perform processing) then messaging is probably a better solution. A message queue reduces the time-dependency between processes because one process can put data in the queue and go on about its business. When the other process is ready, it can pull data from the queue and begin processing.
If you must send data to a legacy system (an older, established system that is still in use) see if there is messaging software available for the legacy system. IBM, for example, makes a messaging product called MQSeries that makes it easy to exchange data with a mainframe. IBM even has a Java library for sending and receiving MQSeries messages.