What you learn in this article
Patterns are often related, thus used together to create larger architectures and designs. For example, imagine that you are responsible for solving a problem that requires applying multiple patterns, and that you will be solving this same problem repeatedly, each time with essentially the same set of patterns. The efficient solution may be to create a composed pattern, which comprises a set of component patterns.
This article extends Part 8 of the developerWorks series, "Build J2EE applications with IBM Rational Software Architect Enterprise Patterns" (see Resources), by showing you how to create a composed pattern. This reusable composite pattern enables you to quickly build Java™ 2 Platform, Enterprise Edition (J2EE™) applications using IBM® Rational®Software Architect tools. You learn how to combine two enterprise patterns in their commonly used configurations to create the composed pattern. You can then apply that single composed pattern to your business information model, and generate the J2EE artifacts for the model and the placeholders for your business logic, the same as if you were to apply the two enterprise patterns separately.
Although the e-business patterns capture the best experience and knowledge of solution development in documented form, as pattern specifications, the IBM Rational Software Architect meta-tool gives you the ability to codify the patterns in reusable software artifacts called pattern-based micro-tools or pattern implementations. In this article, patterns means the codified, reusable, pattern-based micro-tools.
As more patterns are available for reuse, combining patterns can become a more common practice when the solution that you are developing involves multiple lower-level patterns. You can then use these "pattern recipes" to document and guide the aggregate use of selected patterns and other artifacts when you need to solve a problem quickly. Beyond that, composed patterns capture, in a codified pattern form, the common uses and best practices of developing solutions that use multiple patterns. Composed patterns lift the abstraction of software development to a level that is suitable for particular problem domains.
Although patterns may be combined, based on their intents and interactions of input and output parameters, semantic compatibility of the component patterns are not easily analyzed mechanically. This is largely because there are insufficient semantic specifications for patterns, other than input parameter type and multiplicity. For example, the profiles to use, the expected stereotypes of an element to be bound to a pattern parameter, and the expected output of a pattern transformation can, at most, be documented only informally in pattern descriptions.
Despite this constraint, pattern composition is quite analogous to other programming practices in which experience and previous examples usually guide how to use multiple services together to create higher-level services or solutions. The goal of pattern composition is to capture the commonly known uses of patterns that work together. There are few cross-pattern semantic issues when composing the patterns to automate the proven common practices.
An example of creating a composed pattern from two enterprise patterns
Creating a composed pattern has value when you think that the combination of patterns will be repeatedly useful when developing either multiple solutions or solution updates in special problem domains. A composed pattern captures the usage pattern of applying the component patterns and associated artifacts.
This example is drawn from the use of Session Facade and Business Delegate enterprise patterns (see Figure 1). A Session Facade pattern generates a session bean class to serve as the front end of a set of entity bean classes that model business information. The session bean class provides business information services. A Business Delegate pattern generates a plain Java™ class from the session bean class. You can add business logic to the Java class for business clients to access business information through the business logic. The Business Delegate also hides some characteristics of the business services from the clients, such as remoteness and technology choices.
Figure 1. Enterprise pattern relationships
The Session Facade and Business Delegate pattern instances shown in Figure 2 include a number of pattern parameters to customize.
Figure 2. Session Facade and Business Delegate patterns
If you develop many solutions in your environment by applying a Session Facade pattern and a Business Delegate pattern, a composed pattern called Business Delegate Facade, which combines the two components, will be useful.
Patterns are discovered, not invented. The same principle applies to the composed patterns. Therefore, before you attempt to compose a pattern, it is important to review the past uses of your existing patterns to discover whether and how some patterns are often applied together, how their parameters interact, which parameters must be configured, and which parameters often use the same fixed values.
In this example, based on use experience, we know how these two enterprise patterns work together and how their parameters interact. Therefore, we analyze their parameter dependencies and apply the pattern delegations in the Rational Software Architect pattern framework to activate the composed pattern, which performs the operations that the two component patterns previously did separately.
To create the composed pattern called Business Delegate Facade, follow these steps:
- Analyze the input and output of the component patterns.
- Determine the parameters of the composed pattern.
- Analyze the dependencies of the parameters.
- Determine the parameter and dependency delegations
Figure 3 illustrates the sequence and gives a concise summary of each of these steps.
Figure 3. Steps in designing a composed pattern
Also, you may decide either to give parameters a default value or to remove parameter visibility, based on your past use experience with the component patterns. This can further simplify the user experience.
Figure 4 depicts the input/output relationship and parameter dependencies of the two component patterns. The Session Facade parameter of the Session Facade pattern instance specifies the pattern output, or the session bean class, that is created when you manually bind the entity bean classes to the Entity Bean input parameter. After you have created it, the session bean class is manually bound to the Business Service input parameter of the Business Delegate pattern instance. This creates a plain Java class, and the name of that class appears in the Business Delegate output parameter of the Business Delegate pattern instance.
Figure 4. Parameter analysis
2. Composed pattern parameters
Because the Session Facade output parameter of the Session Facade pattern is passed to the Business
Service input parameter of the Business Delegate pattern, a single parameter, Session Bean Class, of the composed pattern called Business Delegate Facade coalesces both of the component pattern parameters. This parameter implements data connection between the two component patterns through Rational Software Architect pattern parameter and dependency delegations.
The new pattern includes a parameter called Business Delegate Class for the plain Java class that the Business Delegate pattern generates. The new pattern also has two additional input parameters:
-
Entity Classesparameter, which corresponds to theEntity Beanparameter of the Session Facade pattern -
Remote Interfaceparameter, which corresponds to theUse Remote EJB Interfacesparameter of the Business Facade pattern
Each parameter is the same type as that of its corresponding parameter in the component pattern. (See Figure 5.)
-
Business Delegate Class: Plain Java class that provides business services -
Session Bean Class: Provides business data services -
Entity Classes: Data model managed and used by business services -
Remote Interface: Indicates whether the remote interface is supported
Figure 5. New pattern parameters
3. Parameter dependency analysis
As the dashed arrows in Figure 4 show, the Session Facade parameter depends on the Entity Bean parameter, and the Business Delegate parameter depends on both the Business Service parameter and the Use Remote EJB Interfaces parameter.
The same parameter dependency relationships must hold in the composed pattern. In Figure 5, the Session Bean Class parameter depends on the Entity Classes parameter, and the Business Delegate Class parameter depends on the Remote Interface parameter. Therefore, the Session Bean Class parameter in the composed pattern represents both the Business Service parameter and the Session Facade parameter in the two component patterns, because of this dependency chain:
Business Delegate > Business Service > Session Facade parameter > Entity Bean.
Thus, in Figure 4, the Business Delegate Class parameter depends on the Session Bean Class parameter. The Business Delegate Class parameter also indirectly depends on the Entity Classes parameter.
The parameters in the composed pattern delegate their operations to those of the component patterns in two ways:
-
Dependency delegation: The dependencies between the composed pattern parameters (for example, between
Business Delegate ClassandSession Bean Class, betweenSession Bean ClassandEntity Classes, and betweenBusiness Delegate ClassandRemote Interface) are delegated to the corresponding dependencies in the component patterns. The additional dependency between theBusiness Delegate ClassandEntity Classesparameters that you see in this analysis can be added to the composed pattern to get a prompt update of theBusiness Delegate Classwhenever theEntity Classesparameter changes. -
Parameter delegation: The
expandoperations of the composed pattern parameters (Business Delegate Class,Session Bean Class,Entity Classes, andRemote Interface) are delegated to the corresponding parameters in the component patterns. Now that theSession Bean Classparameter represents both theSession Facadeparameter and theBusiness Serviceparameter, itsexpandoperation needs to be delegated to both of the component pattern parameters.
Composed pattern implementation
Given the results of the design analysis, you are now ready to codify the composed pattern by following these steps:
- Create the Business Delegate Facade pattern in a Rational Software Architect pattern plug-in project, using the pattern template to add the four parameters and to create the parameter dependencies derived from the design analysis in the previous section. (See Figure 6.)
Figure 6. Composed pattern instance
- In the generated pattern code, at the top of
BusinessDelegateFacade.javafile in the pattern folder, add twoimportcommands for parameter and dependency delegation (see code Listing 1).
Listing 1. Import commands for parameter and dependency delegation
import com.ibm.xtools.patterns.framework.PatternDependencyDelegate;
import com.ibm.xtools.patterns.framework.PatternParameterDelegate;
|
- Inside of the
BusinessDelegateFacadeclass in the same Java file, add twoPatternDefinitionUsagestatements (see Listing 2) to create pattern usage references to the two component patterns.
Listing 2. PatternDefinitionUsage statements
public class BusinessDelegateFacade extends AbstractPatternDefinition {
private final PatternDefinitionUsage businessDelegatePattern =
new PatternDefinitionUsage( new PatternIdentity(
"com.ibm.xtools.patterns.content.j2ee.businessdelegate", "1.0.0",
"com.ibm.xtools.patterns.content.j2ee.businessdelegate.patterns.
businessdelegate.BusinessDelegatePattern", "1.0.0"));
private final PatternDefinitionUsage sessionFacadePattern =
new PatternDefinitionUsage( new PatternIdentity(
"com.ibm.xtools.patterns.content.j2ee.sessionfacade", "1.0.0",
"com.ibm.xtools.patterns.content.j2ee.sessionfacade.patterns.
sessionfacade.SessionFacadePattern", "1.0.0"));
|
- For each parameter that has a dependency on other parameters, add a
PatternDependencyDelegatestatement to the constructor of the parameter's dependency inner class (see Listing 3). In this case: -
Session Bean Classhas a dependency onEntity Classes. Delegate this dependency operation to the corresponding parameter dependency operation in the Session Facade pattern. -
Business Delegate Classhas a dependency onSession Bean Class. Similarly, delegate the dependency operation to the Business Delegate pattern. -
Business Delegate Classalso has a dependency onRemote Interface. Delegate the dependency operation to the Business Delegate pattern.
Listing 3. PatternDependencyDelegate statement
private SessionBeanClass_EntityClassesDependency( AbstractPatternParameter
dependency) {
super(SessionBeanClass.this, dependency);
new PatternDependencyDelegate(this, BusinessDelegateFacade.this.sessionFacadePattern,
new PatternParameterMapping.Provider() {
public void provide(
final PatternParameterMapping.Map map) {
map.map(BusinessDelegateFacade.this.sessionBeanClass, "Session Facade");
map.map(BusinessDelegateFacade.this.entityClasses, "Entity Bean");
}
});
}
private BusinessDelegateClass_SessionBeanClassDependency(AbstractPatternParameter
dependency){
super(BusinessDelegateClass.this, dependency);
new PatternDependencyDelegate(this,BusinessDelegateFacade.this.businessDelegatePattern,
new PatternParameterMapping.Provider() {
public void provide(
final PatternParameterMapping.Map map) {
map.map(BusinessDelegateFacade.this.businessDelegateClass,"Business Delegate");
map.map(BusinessDelegateFacade.this.sessionBeanClass, "Business Service");
}
});
}
private BusinessDelegateClass_RemoteInterfaceDependency(AbstractPatternParameter
dependency) {
super(BusinessDelegateClass.this, dependency);
new PatternDependencyDelegate(this,BusinessDelegateFacade.this.businessDelegatePattern,
new PatternParameterMapping.Provider() {
public void provide(
final PatternParameterMapping.Map map) {
map.map(BusinessDelegateFacade.this.businessDelegateClass, "Business Delegate");
map.map(BusinessDelegateFacade.this.remoteInterface, "Use EJB Remote Interfaces");
}
});
}
|
- As a general rule, add a
PatternParameterDelegatestatement to the constructor of each parameter class of the composed pattern. (See Listing 4.) This is to delegate its expand operation to that of the corresponding parameter in the component patterns. This ensures that all of theexpandoperations of the component parameters can be properly activated from the composed pattern. In this case, this means that you: - Delegate the
Entity Classesparameter to theEntity Beanparameter of the Session Facade pattern. - Delegate the
Remote Interfaceparameter to theUse Remote EJB Interfacesparameter of the Business Delegate pattern. - Delegate the
Session Bean Classparameter to theSession Facadeparameter of the Session Facade pattern and theBusiness Serviceparameter of the Business Delegate pattern. - Delegate the
Business Delegate Classparameter to theBusiness Delegateparameter of the Business Delegate pattern.
Listing 4. PatternParameterDelegate statements
EntityClasses() {
super(BusinessDelegateFacade.this, new PatternParameterIdentity(PARAMETER_ID));
new PatternParameterDelegate(this,BusinessDelegateFacade.this.sessionFacadePattern,
new PatternParameterMapping.Provider() {
public void provide(final PatternParameterMapping.Map map) {
map.map(BusinessDelegateFacade.this.entityClasses, "Entity Bean");
}
});
}
RemoteInterface() {
super(BusinessDelegateFacade.this, new PatternParameterIdentity(PARAMETER_ID));
new PatternParameterDelegate(this, BusinessDelegateFacade.this.businessDelegatePattern,
new PatternParameterMapping.Provider() {
public void provide(final PatternParameterMapping.Map map) {
map.map(BusinessDelegateFacade.this.remoteInterface, "Use Remote EJB Interfaces");
}
});
}
SessionBeanClass(EntityClasses entityClasses) {
super(BusinessDelegateFacade.this, new PatternParameterIdentity(PARAMETER_ID));
new SessionBeanClass_EntityClassesDependency(entityClasses);
new PatternParameterDelegate(this, BusinessDelegateFacade.this.sessionFacadePattern,
new PatternParameterMapping.Provider() {
public void provide(final PatternParameterMapping.Map map) {
map.map(BusinessDelegateFacade.this.sessionBeanClass, "Session Facade");
}
});
new PatternParameterDelegate(this, BusinessDelegateFacade.this.businessDelegatePattern,
new PatternParameterMapping.Provider() {
public void provide(final PatternParameterMapping.Map map) {
map.map(BusinessDelegateFacade.this.sessionBeanClass, "Business Service");
}
});
}
BusinessDelegateClass(SessionBeanClass sessionBeanClass,RemoteInterface remoteInterface) {
super(BusinessDelegateFacade.this, new PatternParameterIdentity(PARAMETER_ID));
new BusinessDelegateClass_SessionBeanClassDependency(sessionBeanClass);
new BusinessDelegateClass_RemoteInterfaceDependency(remoteInterface);
new PatternParameterDelegate(this, BusinessDelegateFacade.this.businessDelegatePattern,
new PatternParameterMapping.Provider() {
public void provide(final PatternParameterMapping.Map map) {
map.map(BusinessDelegateFacade.this.businessDelegateClass, "Business Delegate");
}
});
}
|
Applying your new composed pattern
You can apply the composed pattern to a customer data model, just as you can the Session Facade pattern (see Figure 7). Just follow these steps:
- Create a
Customerentity class. - Specify a class name of
CustomerSBfor theSession Bean Classand generate the session bean class model. - Drag the
Customerclass to theEntity Classesparameter to update the session bean class. - Specify a class name of
CustomerBDfor theBusiness Delegate Class, and then generate the Java class model.
Note: The service stereotype in the generated session bean class does not appear correctly. In this example, before this problem was fixed, we manually added the stereotype before step 4.
Figure 7. Applying your composed pattern
Pattern parameters provide variation points for customization. Depending on the nature of your experience in using them, you may either give a parameter a default value or remove it from the composed pattern by hardcoding. This can further simplify using patterns.
In this example, you may want to give the Remote Interface parameter a default value of true
for the remote interface support, or, instead, to remove the parameter by setting the value in the pattern source code. You may also want to remove the visibility of the intermediary Session Bean Class parameter from the pattern instance if the generated session bean class will not be used by or related to other model elements in the solution domains. A separate article in this series describes the details of this method and the coding.
This article described a general method for creating composed patterns from pre-existing patterns and explained how to design and implement one, using a detailed example. Composed patterns capture the patterns of how you use your existing patterns and provide a high-level abstraction for reusing them in combinations. Therefore, they can further simplify pattern-based development.
When you start building pattern-based solutions, you may want to consider the granularity of the solutions before you decide what patterns you want to compose by combining other patterns. You can apply the steps in this article to create your own composed patterns and hierarchies for reusing them.
The authors thank Lee Ackerman for his detailed review of this article and the many constructive comments that they incorporated.
| Description | Name | Size | Download method |
|---|---|---|---|
| Project Interchange for the composed pattern | BusinessDelegateFacade.zip | 115KB | HTTP |
Information about download methods
Learn
-
"Architecting on demand solutions, Part 8: Build J2EE applications
with IBM Rational Software Architect Enterprise Patterns", IBM developerWorks article (May 2005).
-
"DEV510: Applying the Enterprise Patterns in IBM Rational Software Architect", introductory-level Web-based training course (May 2006).
- Stay current with developerWorks technical events and Webcasts.
-
IBM Rational Software Architect product page: Find technical documentation, how-to articles, education, downloads, and product information about Rational Software Architect.
- Visit IBM's Pattern Solutions and find out what IBM is doing around patterns and reusable assets.
- Browse the technology bookstore for books on these and other technical topics.
Get products and technologies
- Download a free trial version of Rational Software Architect.
- Download IBM product evaluation versions and get your hands on application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
Discuss
- Participate in developerWorks
blogs and get involved in the developerWorks community.
-
Rational Software Architect, Data Architect, Software Modeler, Application Developer and Web Developer forum: Ask questions about Rational Software Architect.

Yi-Hsiu Wei, PhD, is a member of the IBM Software Group Strategy team. He has broad interests and had made contributions in the areas of parallel and distributed systems, security and directory, programming model, transformation, and automation. Dr. Wei has published more than 25 refereed journal articles and conference papers.

Janette Wong is a Senior Technical Staff Member in the IBM Application and Integration Middleware Software group. Her responsibilities include security patterns, digital identities, and Business Process Management (BPM) architecture and development.

Scott E. Schneider is the technical lead of IBM Rational Software Architect patterns tooling. Scott's research interests include pattern formalization, generative programming, domain-specific languages, meta-modeling and model-driven development automation. Previously, he was co-architect of the IBM Rational Rose Data Modeler and IBM XDE Data Modeler products, and he has a background in the design of object-relational mapping tools. He was a lead committer on the Eclipse Test and Performance Tools Platform (TPTP), with a focus on the test execution and automatable services framework. Scott is a member of the IBM Patterns Governance Board (PGB) and of the Association for Computing Machinery (ACM), and he has two pattern-related patents pending.
Comments (Undergoing maintenance)





