J2EE Design Patterns
Goal
To distribute message processing across multiple consumers, allowing multiple messages to be processed in parallel (Figure C-1). Figure C-1. Competing consumers Participants
Interactions
One or more applications send messages to a queue. Multiple consumers access the queue, each reading different messages and processing them. Each message is read from the queue by one and only one consumer. Notes
The Competing Consumers pattern is best implemented using JMS, as Internet mail providers generally do not support multiple readers on a single mailbox terribly well.
Goal
To deliver messages to a client as quickly as possible, while minimizing the complexity of the code, the developer must assemble to handle messages. Participants
Interactions
Incoming messages are delivered to the message server. The application server communicates with the message server and retrieves new messages destined for a particular client. When new messages arrive, the application server calls appropriate client code to process them. Notes
Message-driven EJBs implement the Event-Driven Consumer pattern. JMS also supports implementing event-driven consumers directly. JavaMail supports event-driven consumers via the FolderListener interface, although we do not recommend it. Most event-driven consumer implementations simply push implementation to the application server/application framework level, while still implementing a polling consumer behind the scenes.
Goal
To hide business logic behind a standard façade that can be accessed asynchronously and maintained independently (Figure C-2). Figure C-2. Message façade Participants
Interactions
The client creates a command message and sends it to the message façade using any sort of message transport. The façade receives the message (using a polling consumer or an event-driven consumer) and uses the information it contains to access business tier code to fulfill a use case. Optionally, a return message is sent to the client confirming successful completion of the use case and returning data. Notes
Also see the Business Delegate and Session Façade patterns.
Goal
Decouple the code responsible for the processing of messages from the code responsible for receiving messages. Provide a simpler framework for testing message-handling code. Participants
Interactions
The message client is responsible for retrieving messages from a transport mechanism, via JavaMail, JMS, or other technologies. Once a message is received, it is handed off to a separate message handler object, which is responsible for processing the message content. Notes
The message handler design is a building block for more complex client designs.
Goal
To manage multiple types of messages on a single message channel. Participants
Interactions
Senders transmit messages to a single message channel. Each message includes identifying information, such as headers, that can be used to determine the purpose of the message. The client reads the channel and selects the messages it is capable of handling. Notes
Message selectors can be implemented in JMS using the built-in selection criteria API, which allow you to add SQL-like selection criteria to a Queue or a Topic.
Goal
Allow an application to participate in a messaging exchange without requiring that the application be running 100% of the time and without requiring a continuous two-way connection with the messaging server. Participants
Interactions
As messages for a particular client arrive at the message server, the server stores each incoming message in a holding area. The client periodically contacts the message server and issues a request for all new messages intended for it. The message server transmits all of the held messages to the client, which processes them. Notes
All consumers working with POP3 implement the Polling Consumer pattern. JMS consumers have a wider variety of options, including the Event-Driven Consumer pattern. |