img
Home > Candidate Patterns > Messaging Design Pattern

Messaging Design Pattern

How can we enable the interchange of information (i.e. messages) between components and applications?

Problem

This Messaging design pattern (MDP) can be applied to solve a great variety of problems in many diverse scenarios. A messaging paradigm is widely used in the real world. One of the specific problems that MDP is able to model and solve, is the one associated with providing transparent and secure access to distributed components.

Solution

Since computer applications seek to model the real world, it is only natural to design and write applications using a messaging approach. In the case of our specific access problem, MDP is able to provide transparent access to remote components regardless of the protocol and communication mechanism being used: remote objects are treated as local objects. Design patterns implemented using messaging (adapters, remote proxies and façades) make this possible by hiding the complexities associated with remote APIs.

Application

Design Pattern implementation, Access to distributed components, component/messaging frameworks, ESB, Web services (SOA), Modeling and Business process tools.

Impacts

People need to think in terms of messaging when they model, design and build software applications.

Architecture

Service

Status

Under Review

Contributors

Edgar Galvis

Problem

This design pattern can be applied to solve a great variety of problems in many diverse scenarios. A messaging paradigm is widely used in the real world. Messages are interchanged all around us. Entities are constantly sending, receiving and processing messages. Human beings for instance: when we watch TV, when we talk to a friend, talk over the phone, or send an email message. Right now, you are reading this written message. One of the specific problems that MDP is able to model and solve, is the one associated with providing transparent and secure access to distributed components.

Solution

Since computer applications seek to model the real world, it is only natural to design and write applications using a messaging approach. We can argue that messaging provides a better and more accurate representation (i.e. model) of the real world. As a consequence, software engineering processes are significantly improved by the use of the messaging design pattern.

Participants:

  • Message Sender: Component that sends the message.
  • Message Recipient (Receiver): Component that receives the input message and produces a reply (output message) after processing it. The input message, general in nature, may contain any type of information. The component may be instructed to perform computations based on the input message.
  • Messenger: Intermediary that transfers the message from the sender to the recipient. The sender and the recipient don't need to be concerned about how the message is transferred (communication protocol, message format, encryption/security mechanism, etc.) and the transformations performed on the message along the way. This is the messenger's purpose and responsibility. Similar to the real world, it is often the case that the messenger is not required. The message can be sent directly to the message recipient.
  • Message: any piece of information (i.e. data) that needs to be interchanged between sender and recipient. Two messages are involved: input message and output message (or reply message).

Structure

The messaging design pattern is implemented using the messaging interface (JtInterface). This interface consists of a single method to process the input message and produce a reply message.

img

Messaging Interface

img

Messaging Design Pattern

Application

  • Message Sender: Component that sends the message.
  • Design patterns. The messaging design pattern has been used to implement and/or facilitate the implementation of other well-known design patterns like Gang of Four design patterns (GoF), DAO, J2EE Design patterns, etc. The messaging design pattern also provides a more natural, streamlined and straightforward implementation of other design patterns. Again, we can argue that this is possible because messaging provides an accurate representation of the real world.
  • Remote proxies and application interfaces. The messaging design pattern is particularly well suited for the implementation of remote access. It is able to provide transparent access to remote components regardless of the protocol, technology and communication mechanism being used: remote objects are treated as local objects. Messages can be transferred via Web services, EJBs, RMI, HTTP, Sockets. SSL or any other well-known communication interface. Design patterns implemented using messaging (adapters, remote proxies and façades) make this possible by hiding the complexities associated with remote APIs. The messaging design pattern solves a whole set of problems dealing with remote application interfaces. It also provides significant improvements over traditional methods and technologies. Sender and recipient don't need to be concerned with how messages are transferred.
  • Component based frameworks and design/BPM tools. The messaging design pattern can be utilized to implement component based frameworks: components can be interchangeably plugged into complex framework applications using the “Lego” architecture previously described. These components can also be readily incorporated into UML/BPM diagrams in order to design and implement complex applications. Notice that for components to be used interchangeably, they need to share the same interface. The messaging design pattern provides this common interface.
  • Secure Web Services. The messaging design pattern has been utilized to implement secure web services. This includes Restful web services. A Web service is just another mechanism of communication between heterogeneous applications. Notice that the messaging design pattern doesn't place any restrictions on the message sender and recipient. These components can be running on multiple computers and operating systems. They can also be implemented using multiple computer languages and technologies.
  • Enterprise Service Bus (ESB) components and applications. Messaging has been used to implement ESB components and applications. Once all the building blocks are present (remote proxies, adapters, façades, etc), they can be assembled to create a new application in a fraction of the time required by traditional methods. This is possible thanks to the messaging design pattern and the “Lego” architecture.
  • Secure and Multithreaded applications. The messaging design pattern provides the building blocks required to assemble secure and multithreaded applications in a fraction of the time required by traditional methods. These building blocks are usually provided within the context of a messaging framework.

Impacts

  • Encapsulation. The messaging design pattern maximizes encapsulation. Each component is a self-contained/independent unit. The only mechanism of communication with other components and applications is via messaging.
  • Decoupling. The messaging design pattern minimizes coupling. Again each component is a self-contained unit that can perform independently from the rest of the system.
  • Reusability. The messaging design pattern improves reusability. This is similar to the building blocks in a “Lego” set. Very complex models can be built based on simple pieces that share a simple way of interconnecting them (i.e. common interface). The power of the approach is derived from the number of combinations in which these toy pieces can be assembled. Components that use the messaging design pattern can be interchangeably plugged into complex applications. The components can be assembled in a limitless variety of configurations. The user of a component only needs to know the input/output messages that the component handles. Applications are also able to reuse components from other applications at the component level: a single component can be extracted from another application, provided that the messaging design pattern is being used.
  • QA/Testing process. The messaging pattern facilitates testing and debugging efforts. Components are tested as independent units by sending messages to the component and verifying the expected reply messages (black-box testing). In general, unit testing can be performed via a testing harness. No need to include testing code inside the component code which can be time consuming and lead to the unexpected introduction of software defects.
  • Design process. Components that use the messaging design pattern improve and simplify the design process. The bulk of the design work becomes defining the set of components needed to meet the system requirements and the input/output messages that each component needs to handle. There is a tight correspondence between UML design diagrams and the components needed for the implementation. Since all components share the same messaging interface, they can also be easily added to BPM diagrams. As mentioned earlier, this is similar to building blocks that can be reused and connected in many different ways.
  • Development process. Since each component that relies on messaging is self-contained, a large team of people can cooperate in the development effort without stepping on each other's code/work. In the ideal situation, responsibility for one component/package can be given to an individual. The rest of the team only needs to know the input/output messages that someone else's component is supposed to handle. No need to change someone else's code. The need for creating, maintaining and merging several versions of the code is also minimized or eliminated. Testing/QA engineers can do their testing independently via a testing harness. In general, there is no need to add testing code.
  • Logging and Debugging. Since all the components use the same messaging interface, messages can be logged automatically. This minimizes the need for print/logging statements inside the code which can be time consuming and error-prone. By taking a look at the messages being logged, the user is usually able to quickly track down the message/component that is causing the problem (with minimum or no extra effort).
  • Security. Well-known encryption and authentication mechanisms fit in well with the messaging design pattern. Strong security can be provided by the framework that implements the messaging design pattern. This is done by encrypting and authenticating the messages being interchanged. The sender and the recipient don't need to be concerned with how secure messaging is implemented. This provides strong security while at the same time simplifying the implementation of security. Custom security mechanisms can also be incorporated: sender and receiver need to agree on and implement the message encryption/authentication mechanism to be used.
  • Multithreading and asynchronous messaging. The messaging design pattern is able to handle the complexities associated with multithreading and asynchronous messaging. Components that implement the messaging design pattern are able to execute in a separate/independent thread. This is a natural representation of the real world: each component (entity) is a self-contained unit and executes independently for the rest of the system. Messages can be processed asynchronously using the component's own independent thread. This capability is usually implemented in the context of a component framework. The component doesn't need to add separate logic to handle multithreading which is time consuming, complex and prone to error.
  • Speed of development and cost. Because of all the reasons outlined above, the messaging design pattern is able to substantially improve the speed of development and reduce cost.
  • Quality and software maintenance. Quality and software maintenance efforts are also improved as a result of the all of the above.
  • In order to take full advantage of this design pattern, people need to think in terms of messaging when they model, design and build software applications: independent entities (i.e. components) interchanging messages among each other. This may require learning time and training. Although a messaging approach is natural, intuitive, and consistent with the real world, traditional approaches are based on libraries and method/procedure invocation (both local and remote).
  • Transferring messages between components introduces a small overhead when compared with traditional method/procedure invocation. As computers become faster and faster this becomes a non-issue. Also, the benefits of messaging outweigh this small performance cost.
  • The messaging design pattern encourages a disciplined approach that may have a small impact on the initial development time of a component. Messaging should be the only channel of communication between components. External class methods may still be invoked using the traditional approach. On the other hand, this should be used sparingly in order to minimize coupling and maximize encapsulation. An ideal component is a self-contained unit that interacts with the other components only via messaging. The additional development time is again outweighed by the benefits introduced by messaging. Moreover individual components based on messaging can be purchased or extracted from other applications.

Relationships

  • Message Sender: Component that sends the message.
  • Command and GoF design patterns. The Command design pattern is able to handle requests/operations. On the other hand, the Messaging design pattern is general in nature. It is able to handle any type of information (i.e. message). The Messaging design pattern has been used to implement Command and many of the other GoF design patterns.
  • Enterprise Integration Patterns. Literature has also been published describing messaging in the specific realm of Enterprise Application Integration (EAI).
  • Data Access Objects and J2EE design patterns. These design patterns have been implemented using the Messaging design pattern.

Case Study Example

The messaging design pattern is implemented using the Jt messaging interface (JtInterface). This interface consists of a single method:

public interface JtInterface {
    
    /**
      * Jt messaging interface used for the implementation
      * of the messaging design pattern.
      * Process an input message and return a reply
      */ (output message).
      */
      
       Object processMessage (Object message);
    }
	

The JtInterface is simple but powerful. The simplicity of this interface can be deceiving. One method is all that is needed. It acts as a universal messaging interface that applies to remote and local framework components. This interface handles any type of message (Object class).

The following example sends a message to a remote component/Restful service via a remote proxy. The messaging design pattern is able to handle any communication protocol/technology (Web Service, EJBs, RMI, sockets, SSL, etc.). To illustrate the implementation, several UML diagrams are included. The first UML sequence diagram shows how the Messaging design pattern is used to implement the Proxy design pattern. The second diagram shows how both design patterns are used to implement web services. The next diagram demonstrates how another communication interface is implemented by plugging in an additional component. The last diagram shows the implementation of secure web services. For clarity sake, the message sequence and the intrinsic processMessage() method have been removed from these diagrams.

img

Proxy implementation using the Messaging Design Pattern. The proxy forwards the message to the subject.

img

Web Service implementation using the Messaging Design Pattern.

img

Implementation of remote communication interfaces using the Messaging Design Pattern.

Note: Any other communication protocol/technology can be handled (Axis, EJB, RMI, sockets, SSL, etc). It is just a matter of replacing the HTTP Adapter and plugging in the appropriate adapter for the remote interface. The messaging design pattern and architecture make this possible. The other components remain unchanged. This design pattern solves a whole family of problems associated with remote APIs.

img

Encrypted web service implemented by plugging in a component to perform message encryption/decryption.

/**
    * Send a message to a remote component/Restful service using
    * a remote proxy. Secure/Encrypted messaging may be used.
    * The messaging design pattern provides transparent access
    * to remote components.
    */
    
    public static void main(String[] args) {
    
      JtFactory factory = new JtFactory ();
      String sReply;
      JtRestProxy proxy;
      String url = "http://localhost:8080/JtPortal/JtRestService";
      
      // Create an instance of the remote Proxy.
      
      proxy = (JtRestProxy)
       factory.createObject (JtRestProxy.JtCLASS_NAME);
       
      proxy.setUrl(url);
      proxy.setClassname ("Jt.examples.Echo");
       
       // Specify that secure/encrypted messaging should be used.
       
      proxy.setEncrypted(true);
       
       // Send the message to the remote component/service via
       // the remote proxy.
       
      sReply = (String)
        factory.sendMessage (proxy, "Welcome to Jt messaging ...");
       
        // The remote component will echo the input message.
       
      System.out.println ("Reply:" + sReply);
       
       
    }