Skip to main content

The Go-ForIt Chronicles: Memoirs of eXtreme DragonSlayers, part 13

Using command patterns to enhance performance

Sandeep Desai (sandeep@us.ibm.com), Software Engineer, IBM
Sandeep Desai
Sandeep Desai is an e-business Architect in IBM's Developer Relations Technical Consulting in Austin, Texas. Sandeep works with IBM's Business partners, from startups to large firms, helping to evangelize, educate, and enable them on IBM's e-business platform. Among Sandeep's technical certifications are: IBM Certified e-business Solution Advisor, IBM Certified e-business Solution Designer, IBM Certified e-business Solution Technologist, IBM Certified Specialist - WebSphere Application Server , IBM Certified Systems Expert - WebSphere Application Server. You can contact Sandeep at sandeep@us.ibm.com.
Venkata Nagalla (nagalla@us.ibm.com), Software Engineer, IBM
Venkata Nagalla
Venkat Nagalla is an e-business Architect in IBM's Developer Relations Technical Consulting in Austin, Texas. Venkat works with both small and large IBM Business partners, helping to evangelize, educate and enable them on IBM's e-business platform. Venkat has 18 years of experience in the software engineering field with IBM. His areas of expertise include object-oriented design and development and, most recently, IBM WebSphere Business Components. Venkat holds IBM Certified e-business Solution Advisor and Sun Java Programmer certifications. You can contact Venkat at nagalla@us.ibm.com.

Summary:  In this thirteenth part of our series about the DragonSlaying technical consulting team, Sandeep Desai and Venkat Nagalla describe how the team leverages the command framework for big performance benefits. They discuss the architectural and design issues that prompted the team to choose command beans, and include sample code showing the application design.

Date:  01 Dec 2001
Level:  Advanced
Activity:  610 views

The Go-ForIt architecture

The Go-ForIt.com project is an e-business application developed by the DragonSlaying technical consulting team in the IBM Developer Relations organization. Go-ForIt is built on a logical three-tier architecture, a programming model advocated by J2EE, and uses the eXtreme Programming (XP) development methodology (see part 2 in the Go-ForIt series, eXtreme programming: deceptively simple innovation). Go-ForIt.com implements the model view controller (MVC) concept. In this article, we will discuss how to use the command framework in an n-tier architecture to reduce overhead and improve performance.

The components of the Go-ForIt.com application are:

First tier
The browser
Second tier
Servlets, JavaServer Pages (JSPs) technology, command beans and helper JavaBeans components
Third tier
Business logic, in Enterprise JavaBeans (EJB) technology, and a database


What is a command?

Sometimes it is necessary to issue requests to objects without knowing anything about the operation being requested or the receiver of the request. The command pattern, which is a well documented pattern, allows you to encapsulate the request as an object and the resulting request object can be stored or passed around.

A command is a Java class that:

  • Corresponds to a specific business logic task
  • Has a simple, uniform usage pattern
  • Hides logic from the user interface (UI)
  • Hides the specific connector interfaces
  • Caches the information returned upon execution of the command

Generally, commands are implemented as JavaBeans components with the following methods. There must be a method defined for:

  • Each input property xxx: Void setXxx (Xxx xxx);
  • Each output property: Xxx getXxx();
  • Execution of the task: public boolean execute();

There can be other methods: to do(), undo(), and reset() the command.


How does Go-ForIt.com use commands?

The Go-ForIt.com application uses commands to let the UI objects make requests to the back-end without knowing the what, how, and why of the controller objects or EJBs it needs to talk to. For this reason we developed commands for all possible user functions. We identified commands by having a concrete command class for every user level function. Our UI is in HTML/JSP form, which invokes a servlet, so we developed a concrete command for every function that the servlet calls.

Implementing the command pattern involved separation of tasks by role, such as UI developer and the Java business logic developer. Thus, the commands are used to communicate between the controller residing on the second tier and the model residing on the third tier in our MVC architecture. The servlet has no knowledge of what back-end objects it needs to communicate with to get a unit of work done; all it does is instantiate a command object and then set the input parameter of the command and call its execute method. When the command has finished performing the business logic, the result, if any, is stored in the command, so that the servlet can get the result values from the command object. The command pattern reduced the overhead of cross-tier communication in our application by caching the results.

The following diagram shows the interactions between the objects.


Figure 1. Sequence Diagram
Sequence Diagram

Code samples

The code in this section will help you understand how the command beans play a role in our application. The examples are part of the code that implements the User Registers user story (see Resources). The Registration.jsp collects all the personal information about the user, then calls the registration servlet. In the registration servlet we get all the data from the request object and store it in a client side Java bean called UserDataBean (see part 4 in the Go-ForIt series, "Bean" there, done that: Using client-side beans for component independence).

The next job of the registration servlet is to exercise the logic to register the user with the application. The process involves calling the UserController session bean and user entity bean, which perform some additional logic and then persist the user in the database. There's a lot of information the registration servlet has to know, if it were to do the whole task by itself. The developers who typically write the servlet are well versed with the application flow functions. Now, they need to know all the back-end details of how to call the appropriate EJB components to get the task done. We encapsulated all the back-end details in the UserRegisters command bean, so all the registration servlet has to do is call the execute method of the bean and the job gets done when the command returns.


Registration Servlet calls the UserRegistersCommandBean
public void performTask(
	javax.servlet.http.HttpServletRequest req,
	javax.servlet.http.HttpServletResponse res) {

	UserDataBean user = new UserDataBean();
	
	//instantiate the Command Bean 

         UserRegistersCommandBean dataCommand = new UserRegistersCommandBean(); try { /* * Retrieve the form fields */ user.setAltphone(req.getParameter("alternatePhone")); user.setCcname(req.getParameter("nameOnCreditCard")); ........... /* * Update database with new user information */ try { //passing the user object to Command Bean
                dataCommand.setUser(user);
                //calling the execute method of the Command Bean
                dataCommand.execute(); } catch (Exception e) { ........ } //if no exceptions then forward the request to appropriate // results page
........ /* Forward to HTML View JSP */ if (userType.equals(UserDataBean.CUSTOMER)) { /* Forward to HTML View JSP */ getServletConfig() .getServletContext() .getRequestDispatcher("pages/customer_main_menu.jsp") .forward(req, res); } else { ......... } } catch (Throwable t) { ........ } }

Our commands are designed to do one task only, which keeps our commands simple and easy to maintain. Our UserRegisters command bean has:

  • A default constructor
  • A setUser method that allows the calling object, in our case the servlet, to set the UserDataBean in the command
  • An execute method that has the logic to perform the task
  • A helper method getInitialContext(), which returns the initial context, and getUserControllerHome(), which encapsulates the EJB component look-up logic

UserRegisters Command Bean
package com.goforit.command;

import java.rmi.*;
import com.goforit.exception.*;
import javax.ejb.*;
import java.util.*;
import javax.naming.*;
import com.goforit.ejb.*;
import javax.rmi.*;
/**
 * Command to register a new user
 */
public class UserRegistersCommandBean {
   private InitialContext _initialContext = null;
   private UserControllerHome _userControllerHome = null;
   private String _userControllerJndiName = "com/goforit/ejb/UserController";
   private com.goforit.user.UserDataBean _user;
/**
 * UserRegistersCommandBean constructor comment.
 */
public UserRegistersCommandBean() {
	super();
}
/**
 * Performs task of persisting user in the database
 * by calling EJBs at back end
 * @param user com.goforit.user.User
 * @exception com.goforit.exception.DuplicateUserException 
 * The exception description.
 */ 
public void execute()
    throws com.goforit.exception.DuplicateUserException, 
    CreditCardNotAuthorizedException, 
    InvalidCreditCardNumberException, com.goforit.exception.CommandException{
    
    try {
    	_userControllerHome = getUserControllerHome();
     	UserController	userController = _userControllerHome.create();
    	userController.registerUser(_user);
    } catch (java.rmi.RemoteException e) {
    
    	if ((e.toString().indexOf("DuplicateUserException")) > 1) {
    		throw new com.goforit.exception.DuplicateUserException();
    	}
    	if ((e.toString().indexOf("CreditCardNotAuthorizedException")) > 1) {
    	   throw new com.goforit.exception.CreditCardNotAuthorizedException();
    	}
    	   if ((e.toString().indexOf
    	     ("InvalidCreditCardNumberException")) > 1) {
    	   throw new com.goforit.exception.InvalidCreditCardNumberException();
    	}
    	
    
    } catch (CreateException e) { 
    	throw new com.goforit.exception.CommandException(e.toString());
    }
}
/**
 * Getter for the initialContext property.
 * This method uses com.ibm.ejs.ns.jndi.CNInitialContextFactory to obtain an
 *  initial naming context.
 * @return InitialContext The initial naming context.
 */
private InitialContext getInitialContext() throws NamingException {
	if (this._initialContext == null) {
	   // Get the initial context
	   Properties p = new Properties();
	   // Use IBM name services
	   p.put(javax.naming.Context.PROVIDER_URL, "iiop://localhost:900/");
	   p.put(
	      javax.naming.Context.INITIAL_CONTEXT_FACTORY,
		com.ibm.ejs.ns.CosNaming.NameServer.CONTEXT_FACTORY_CLASS);
	   try {
	      _initialContext = new InitialContext(p);
	      } catch (NamingException e) {
		throw new NamingException(e.toString());
	              } 
	} 
	return this._initialContext;
}
/**
 * Getter for the incrementHome property.
 * This method uses the initial naming context to lookup
 * the entry for the IncrementHome instance.
 * @return The UserControllerHome instance.
 */
private UserControllerHome getUserControllerHome() {
	if (this._userControllerHome == null) {
	   try {
           InitialContext initContext = getInitialContext();
           // The default JNDI name for Enterprise Java Beans created
           // in VisualAge for Java is the fully-qualified name of the
           // remote interface, with periods replaced by forward slashes.
           String jndiName = UserController.class.getName().replace('.', '/');
           Object o = initContext.lookup(jndiName);
           this._userControllerHome = (UserControllerHome) 
	         PortableRemoteObject.narrow(o, UserControllerHome.class);
       } catch (NamingException e) {
		.....
	     } 
   } 
      return this._userControllerHome;

}
/**
 * Sets the user property (com.goforit.user.User) value.
 * @param city The new value for the property.
 * @see #getCity
 */
public void setUser(com.goforit.user.UserDataBean user) {
	_user = user;
}
}

We implemented commands to execute locally in Go-ForIt.com, which means command objects execute in the same Java virtual machine (JVM) as the calling servlet. The command can also be implemented to execute remotely on another server, where the data resides. For more information, see the "Patterns Development Kit" listed in Resources.

Commands in e-business applications add value because they:

  • Are implemented as serialized objects, can be streamed to any server supporting Java access to its resources, and can handle multiple protocols
  • Allow data caching
  • Make it easy to get access to the output data
  • Make stable boundary business logic and UI logic

Conclusion

Command beans are Java beans that have a specific behavior. They help control and encapsulate the execution logic so you can control the bean selection and sequencing, queue them, and otherwise manipulate them. Commands help decouple the object that invokes the operation from the one that knows how to perform it. They help improve performance by creating a unit of work and executing it closer to the data on which the operation needs to be performed.


Stay tuned...

Watch for our next installment of the Go-ForIt chronicles, where we'll cover JUnit testing of EJBs in VisualAge for Java. To see the previous articles in our tale of dragonslaying, go to our overview.


Resources

About the authors

Sandeep Desai

Sandeep Desai is an e-business Architect in IBM's Developer Relations Technical Consulting in Austin, Texas. Sandeep works with IBM's Business partners, from startups to large firms, helping to evangelize, educate, and enable them on IBM's e-business platform. Among Sandeep's technical certifications are: IBM Certified e-business Solution Advisor, IBM Certified e-business Solution Designer, IBM Certified e-business Solution Technologist, IBM Certified Specialist - WebSphere Application Server , IBM Certified Systems Expert - WebSphere Application Server. You can contact Sandeep at sandeep@us.ibm.com.

Venkata Nagalla

Venkat Nagalla is an e-business Architect in IBM's Developer Relations Technical Consulting in Austin, Texas. Venkat works with both small and large IBM Business partners, helping to evangelize, educate and enable them on IBM's e-business platform. Venkat has 18 years of experience in the software engineering field with IBM. His areas of expertise include object-oriented design and development and, most recently, IBM WebSphere Business Components. Venkat holds IBM Certified e-business Solution Advisor and Sun Java Programmer certifications. You can contact Venkat at nagalla@us.ibm.com.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Sample IT projects
ArticleID=10152
ArticleTitle=The Go-ForIt Chronicles: Memoirs of eXtreme DragonSlayers, part 13
publish-date=12012001
author1-email=sandeep@us.ibm.com
author1-email-cc=
author2-email=nagalla@us.ibm.com
author2-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).