Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Web services programming tips and tricks: Learn simple, practical Web services design patterns, Part 2

Encapsulate business logic with a command facade pattern

James Snell (jasnell@us.ibm.com), Software Engineer, IBM, Software Group
Author photo
James Snell is a member of the IBM Emerging Technologies Toolkit team and has spent the past few years focusing on emerging Web services technologies and standards. He maintains a weblog on developerWorks focused on emerging technologies.

Summary:  Part 2 of this series continues a discussion focusing on the application of well-defined and proven Web application design strategies to the world of Web services with an introductory look at the Command Facade Pattern.

Date:  26 Oct 2004
Level:  Intermediate
Also available in:   Russian  Japanese

Activity:  15953 views
Comments:  

In the previous installment of this series, I discussed the application of a programming strategy leveraging the Java Messaging Service to implement an asynchronous programming model for a Web service. Here, I continue to focus on the use of simple, proven design patterns within a Web services environment. My goal is to provide practical examples that offer you alternative ways of coding service implementations to meet specific operational goals.

The command facade pattern

Two patterns that are very familiar to Web application developers are the facade and command patterns. The command facade pattern is a combination of these two designed specifically for a service-oriented environment. As such, it incorporates the fundamental aspects of both of the source patterns, yet does so in a way that makes sense to developers implementing Web services interfaces described using WSDL and made accessible through SOAP messages.

The command pattern is distinguished by the encapsulation of distinct activities into reusable objects whose behavior can be parameterized per request.


Figure 1. The Command Pattern
The Command Pattern

Command objects can be either stateful or stateless. A stateful command maintains the internal state of its data and variables specific to each individual use. Stateful command instances are generally used only once, or are pooled and recycled once the client is done with it. The assignment of parameters to stateful commands occurs either when the object instance is created or immediately prior to command invocation through the setting of attributes. Stateless command instances maintain no internal state, and multiple clients can use them concurrently without requiring pooling or recycling. The assignment of parameters to stateless commands occurs as input to that command's invocation method.

The facade pattern uses a single high-level application component that serves to encapsulate interactions with subordinate components with the goal of simplifying interactions with the system. In other words, a facade can simplify a more complicated interface between the client and the service provider (or even multiple subordinate components).


Figure 2. The facade pattern
The facade pattern

Like Commands, Facades may be stateful or stateless. A stateful Facade maintains an internal state in between client calls to operations defined on the facade. A stateless Facade maintains no internal memory of previous operations, therefore relying on necessary state to be passed in with each method invocation.

The command facade pattern combines these two approaches by introducing a facade interface that sits in front of one or more command objects. The goal of the pattern is to achieve the same kind of business logic encapsulation achieved by the command pattern while presenting a less complicated, more user-friendly interface to potential clients.


Figure 3. The command facade pattern
The command facade pattern

In a Web services world, the facade component of the command facade pattern correlates with the WSDL-described portType, with a one-to-one relationship between the methods defined on the facade and the operations defined on the port type. Each method can, in turn, invoke one or more encapsulated command objects in order to carry out the specific operation. Given a typical Java Web service, in which a single Java class backs a single WSDL portType, the primary goal of this pattern is to move business logic out of the service implementation class and into distinct business objects that are more easily managed and evolved over time.


Implement the example commands

The command facade pattern consists of two distinct types of objects: the Command and the Facade. The design of the Facade is directly related to the Commands to which it will delegate, including the various parameterization options that each type of Command exposes. Therefore, the key to properly designing a command facade implementation is to first design the commands and, from there, define an appropriate facade interface.

This simple example application defines two eminently useful operations that convert input strings either to upper or lower case. Each of these highly complex and computationally intensive operations are encapsulated into two stateless command objects.

Before you begin, however, you need to define the base Command interface.


Listing 1. Command.java
package com.ibm.developerworks.wspattern.two;

public interface Command {
  public CommandModel execute(CommandModel model);
}

The Command interface defines only a single method, called execute, that accepts a single parameter, called CommandModel. CommandModel is essentially a placeholder interface that specific command implementations implement for the purpose of allowing the command objects' users to pass-in parameters that are specific to that command implementation.


Listing 2. CommandModel.java
package com.ibm.developerworks.wspattern.two;

public abstract class CommandModel {}

Because each of the business operations accept as input a single text string, both operations use the same CommandModel implementation shown in Listing 3.


Listing 3. CaseCommandModel.java
package com.ibm.developerworks.wspattern.two.commands;

import com.ibm.developerworks.wspattern.two.CommandModel;

public class CaseCommandModel 
  extends CommandModel {

  private String string;

  public String getString() {
    return string;  
  }
  
  public void setString(String string) {
    this.string = string;
  }
}


Listing 4. UppercaseCommand.java
package com.ibm.developerworks.wspattern.two.commands;

import com.ibm.developerworks.wspattern.two.Command;
import com.ibm.developerworks.wspattern.two.CommandModel;

public class UppercaseCommand 
  implements Command {

  public CommandModel execute(CommandModel model) {  
    if (!(model instanceof CaseCommandModel)) {
      throw new IllegalArgumentException("Invalid command model");
    } else {
      CaseCommandModel umodel = (CaseCommandModel)model;
      if (umodel.getString() == null) {
        throw new IllegalArgumentException("Invalid command model");
      } else {
        umodel.setString(umodel.getString().toUpperCase());
      }
      return umodel; 
    }
  }
}


Listing 5. LowercaseCommand.java
package com.ibm.developerworks.wspattern.two.commands;

import com.ibm.developerworks.wspattern.two.Command;
import com.ibm.developerworks.wspattern.two.CommandModel;

public class LowercaseCommand 
  implements Command {

  public CommandModel execute(CommandModel model) {  
    if (!(model instanceof CaseCommandModel)) {
      throw new IllegalArgumentException("Invalid command model");
    } else {
      CaseCommandModel umodel = (CaseCommandModel)model;
      if (umodel.getString() == null) {
        throw new IllegalArgumentException("Invalid command model");
      } else {
        umodel.setString(umodel.getString().toLowerCase());
      }
      return umodel; 
    }
  }
}

Note that both the LowercaseCommand and UppercaseCommand objects store no internal state. Rather, everything each command needs to execute is passed in as part of the CommandModel parameter. Also note that the execute method returns a CommandModel. A command may return any CommandModel implementation it wishes. In the case of the examples above, the same CommandModel object that is passed into the command is updated and returned back to the calling application. This behavior is not required, however.


Implement the facade

The goal of the facade is to simplify and centralize access to the underlying command objects in order to make those commands more accessible as a WSDL-described Web service. To achieve this goal, methods are defined on the Facade interface that allow the various parameterization options exposed by the underlying commands to be passed in as parameters to the facade methods. A single method on the Facade interface can execute one or more command objects, so the facade input parameters and the method return value need to be well chosen.

For this example, the facade interface exposes one public method for each command, as illustrated in Listing 6.


Listing 6. CommandFacadeService_SEI.java
package com.ibm.developerworks.wspattern.two;

public interface CommandFacadeService_SEI extends java.rmi.Remote {
   public java.lang.String toUpper(java.lang.String string);
   public java.lang.String toLower(java.lang.String string);
}

The implementation of this interface involves having each of the toUpper and toLower operations delegate to the appropriate command objects.


Listing 7. CommandFacadeService.java
package com.ibm.developerworks.wspattern.two;

import com.ibm.developerworks.wspattern.two.commands.LowercaseCommand;
import com.ibm.developerworks.wspattern.two.commands.UppercaseCommand;
import com.ibm.developerworks.wspattern.two.commands.CaseCommandModel;

public class CommandFacadeService {

  private static final String CMD_TOUPPER = "toUpper";
  private static final String CMD_TOLOWER = "toLower";

  private static java.util.HashMap commands = 
    new java.util.HashMap();
  static {
    commands.put(CMD_TOUPPER, new UppercaseCommand());
    commands.put(CMD_TOLOWER, new LowercaseCommand()); 
  }

  private static Command getCommand(String name) {
    return (Command)commands.get(name);
  }

  public String toUpper(String string) {
    CaseCommandModel model = new CaseCommandModel();
    model.setString(string);
    model = (CaseCommandModel)getCommand(CMD_TOUPPER).execute(model);
    return model.getString();
  }

  public String toLower(String string) {
    CaseCommandModel model = new CaseCommandModel();
    model.setString(string);
    model = (CaseCommandModel)getCommand(CMD_TOLOWER).execute(model);
    return model.getString();   
  }
}

Note that because the UppercaseCommand and LowercaseCommand objects are stateless, you create a static cache of instances that are invoked rather than invoking a new instance every time each of the toUpper and toLower methods is invoked.

Once the facade interface has been implemented, the final step is to expose it as a Web service. Assuming the class is being exposed as a JSR-109-compliant Web service, I highly recommend the use of a tool such as IBM® WebSphere® Studio Application Developer (Application Developer) to generate all of the necessary deployment artifacts. To make things easier for you, I have included for download a ZIP file containing full source in the form of Application Developer projects and an EAR file containing the compiled source of the example application. You can download the files by clicking the Code icon at the top or bottom of this tip.


Wrap-up

The key advantage of the command facade pattern is that it allows the business logic behind a Web service implementation to be encapsulated into distinct objects that are more easily managed and evolved over time. As long as the inputs and outputs of the command implementations remain constant, changes in business logic do not need to impact the Web services implementation layer. Further, implementing command objects in this way allows business logic to be reused in other areas of your Web application.

The example given in this article focused exclusively on a stateless facade using stateless commands. Using mechanisms such as those provided by HTTP Sessions or those defined in the WS-Resource Framework, you could easily extend this model to support the use of stateful facades, allowing for some very interesting possibilities.



Downloads

DescriptionNameSizeDownload method
WebSphere deployable EAR filews-tip-altdesign2ear.ear701 KB HTTP
Example program source filesws-tip-altdesign2code.zip719 KB HTTP

Information about download methods


Resources

About the author

Author photo

James Snell is a member of the IBM Emerging Technologies Toolkit team and has spent the past few years focusing on emerging Web services technologies and standards. He maintains a weblog on developerWorks focused on emerging technologies.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and Web services
ArticleID=23255
ArticleTitle=Web services programming tips and tricks: Learn simple, practical Web services design patterns, Part 2
publish-date=10262004
author1-email=jasnell@us.ibm.com
author1-email-cc=