Sun Java Solaris Communities My SDN Account Join SDN
 
J2EE

Sun Java Center J2EE Patterns

 

View Helper

Context

System handles web requests. Presentation processing requires generating a view based on a template and dynamic model.

Problem

Presentation tier changes occur often and are difficult to develop and maintain, due to the combination of business data access logic and the presentation formatting logic. This makes the system less flexible, less reusable, and generally less resilient to change.

Intermingling the business and systems logic with the view processing also reduces modularity and also provides a poor separation of roles among web-production and software development teams.

Forces

  • Business data assimilation requirements are non-trivial.
  • Embedding business logic in the view promotes a copy-and-paste type of reuse. This causes maintenance problems and bugs because a piece of logic is reused in the same or a different view by simply duplicating it in the new location.
  • It is desirable to promote a clean separation of labor by having different individuals fulfill the roles of software developer and web-production team member.
  • One view is commonly used to respond to a particular business request.

Solution

The View delegates content retrieval to its helpers, which serve as the data model and business data adapters. Presentation business logic is encapsulated in the Helper and sits between the View and the business tier.

There are multiple strategies for implementing the view component. The JSPView Strategy suggests using a JSP as the view component. This is the preferred strategy, and it is the one most commonly used. The other principal strategy is the ServletViewStrategy, which utilizes a servlet as the view (See the Strategies section for more information).

Encapsulating business logic in a helper instead of a view makes our application more modular and facilitates component reuse.

Multiple clients, such as controllers and views, may leverage the same helper to retrieve and adapt a similar model state for presentation in multiple ways. The only way to reuse logic embedded in a view is by copying-and-pasting it elsewhere. Furthermore, copy-and-paste duplication makes a system harder to maintain, since the same bug potentially needs to be corrected in multiple places.

A signal that one may need to apply this pattern to existing code is when scriptlet code begins to clutter the JSP view. The overriding goal when applying this pattern, then, is the partitioning of business logic outside of the view. While some logic is best encapsulated within helper objects, other logic is better placed in a centralized component that sits in front of the views and the helpers; Logic that is common across multiple requests, such as authentication checks or logging services, for example. Refer to the DecoratingFilter and FrontController patterns for more information on these issues.

This pattern focuses on recommending ways to partition your application responsibilities. For related discussions about issues dealing with directing client requests directly to a View, please refer to the DispatcherView pattern.

Structure

The following class diagram represents the View Helper pattern:

 

Participants and Responsibilities

The following sequence diagram represents the View Helper pattern:

View

A View represents and displays information to the client. The information that is used in a display is retrieved from a model. Helpers support Views by encapsulating and adapting a model for use in a display.

Helper

A Helper is responsible for helping a View or Controller complete its processing. Thus, Helpers have numerous responsibilities, including gathering data required by the View and adapting [See GoF Adaptor pattern] this data model for use by the View. Helpers can service requests for data from the View by simply providing access to the raw data or by formatting the data as web content.

A View may work with any number of Helpers, which are typically implemented as JavaBeans (JSP 1.0) and Custom Tags (JSP 1.1+). Additionally, a Helper may represent a Command object, a Delegate (see Business Delegate pattern), or an XSL Transformer, which is used in combination with a stylesheet to adapt and convert the model into the appropriate form.

 

Strategies

 
JSP View Strategy

The JSPView Strategy suggests using a JSP as the view component. This is the preferred strategy to the ServletView Strategy. While it is semantically equivalent to the Servlet View Strategy, it is a more elegant solution and is more commonly used.

 

Servlet View Strategy

The ServletView Strategy utilizes a servlet as the view. It is semantically equivalent to the preferred JSPView Strategy. However, the ServletView Strategy is often more cumbersome for the software development and web production teams because it embeds markup tags directly within the Java code. When tags are embedded within the code, the view template is more difficult to update and to modify. Additionally, intermingling Java code and markup tags creates a poor separation of user roles within the project and increases the dependencies on the same resources among multiple members of different teams. When an individual works on a template containing unfamiliar code or tags, it increases the likelihood of accidental change introducing problems into the system. There is also a reduction in work environment efficiency (too many people sharing the same physical resource) and an increase in source control management complexity.

These problems are more likely to occur in larger enterprise environments that have more complicated system requirements and that use teams of developers. They are less likely to occur with small systems that have simple business requirements and use few developers, because the same individual may likely fill the roles mentioned above. However, keep in mind that often projects start small-with simple requirements and few developers-but often ultimately evolve to become sophisticated enough to benefit from these suggestions.

 

JavaBean Helper Strategy

The Helper is implemented as a JavaBean. Using Helpers results in a cleaner separation of the View from the business processing in an application, since business logic is factored out of the View and into the helper component. In this case the business logic is encapsulated in a JavaBean, which aids in content retrieval and adapts and stores the model for use by the View.

Using the 'JavaBean Helper Strategy' requires less up-front work than does the 'Custom Tag Helper Strategy', since JavaBeans are more easily constructed and integrated into a JSP environment. Additionally, even the most novice developers understand JavaBeans. This strategy is also easier from a manageability standpoint, since the only resulting artifacts are the completed JavaBeans.

 

Custom Tag Helper Strategy

The helper is implemented as a Custom Tag (JSP 1.1+ only). Using helpers results in a cleaner separation of the View from the business processing in an application, since business logic is factored out of the View and into the helper component. In this case the business logic is encapsulated in a custom tag component, which may aid in content retrieval and adapts the model for use by the View.

Using the 'Custom Tag Helper Strategy' requires more up-front work than does the 'JavaBean Helper Strategy', since custom tag development is moderately complicated relative to JavaBean development. Not only is there more complexity in the development process, but there is much more complexity with respect to integrating and managing the completed tags. Numerous artifacts must to be generated with which the environment needs to be configured to use this strategy, including the tag itself, a tag library descriptor, and configuration files.

 

BusinessDelegate as Helper Strategy

Helper components often make distributed invocations to the business tier. We suggest using a BusinessDelegate in order to hide the underlying implementation details of this request, such that the Helper simply invokes a business service without knowing details about its physical implementation and distribution (See the Business Delegate Pattern).

Both a Helper and a BusinessDelegate may be implemented as a JavaBean. Thus, one could combine the notion of the Helper component and the BusinessDelegate, implementing the BusinessDelegate as a specialized type of Helper. One major distinction between a Helper and a Business Delegate, though, is as follows: A Helper component is written by a developer working in the Presentation Tier, while the Delegate is typically written by a developer working on the Services in the Business tier (The Delegate may also be provided as part of a framework). If there is some overlap in these developer roles, then the 'Business Delegate as Helper' is a strategy to consider.

 

Helpers

JavaBean Helpers are best used for aiding in content retrieval and storing and adapting the model for the View. JavaBean helpers are often used as command objects, as well.

Like JavaBean Helpers, Custom Tag Helpers may fulfill each of these roles, except for acting as a command object. Unlike JavaBean Helpers, Custom Tag Helpers are well suited to doing control flow and iteration within a View. Custom Tag Helpers used in this way encapsulate logic that would otherwise be embedded directly within the JSP, as scriptlet code. Another area where Custom Tag Helpers are preferred is formatting raw data for display. A Custom Tag is able to iterate over a collection of results, format those results into an HTML table, and embed the table within a JSP View without requiring any Java scriptlet code.

Consider an example where a web client is requesting account information from a system, as shown in the following sequence diagram. There are five helpers shown in this diagram. The four JavaBean Helpers are the AccountCommand object, Account object, AccountDAO, and AccountDetails. The sole Custom Tag Helper is the TableFormatter object.

click to enlarge

The Controller handles the request. It creates or looks up the appropriate command object, which is implemented as a JavaBean Helper. In this case, it is a command object that processes requests for Account information. The Controller invokes the Command object, which asks a JavaBean Account object for information about the account. The Account object invokes the Business Service, asking for these details, which are returned in the form of a Value Object (see Value Object pattern), implemented as a JavaBean.

So how does the Account object access the Business Services. Let us examine two cases, one simple and the other more sophisticated. In the more simple case, imagine that a project is taking a phased approach, phasing in EJB into the Business Tier over time. Assume at the moment that the database is being accessed via JDBC calls from the presentation tier. In this case, the Account object uses a Data Access Object (see Data Access Object pattern), hiding the underlying implementation details of accessing the database. The Data Access Object knows what SQL queries are necessary to retrieve the information. These details are hidden from the rest of the application, reducing coupling and making each component more modular and reusable. This case is described in the previous sequence diagram.

When the architecture becomes more sophisticated, and EJB is introduced in the Business Tier, then the Data Access Object is replaced with a Business Delegate (see Business Delegate pattern), typically written by the developers of the Business Service. The Delegate hides the implementation details of EJB lookup, invocation, and exception handling from its client. It might also improve performance by providing caching services. Again, the object reduces coupling between tiers, improving the reusability and modularity of the various components. Regardless of the specific implementation of this object, its interface may remain unchanged during this transition. The following sequence diagram describes this scenario after the transition to the Business Delegate:

click to enlarge

The Command object now has a handle to the AccountDetails object, which it stores before returning control to the Controller. The Controller dispatches to the appropriate View, called AccountView.jsp. The View then grabs a combination of raw data and formatted data from the Details Helper and the TableFormatter Helper, respectively. The TableFormatter Helper is implemented as a Custom Tag that cycles through the raw data and formats it into an HTML table for display. As stated, this conversion requires no scriptlet code in the View, which would be necessary to perform the same functionality with a JavaBean Helper.

Additionally, the Account object or the Details Helper could provide convenience methods to adapt the raw data in other ways. While such methods would not introduce HTML markup into the data, they might provide different combinations of data. An example is to return the full name of the user in various formats, such as Last-comma-First or First Last, etc.

The completed View is then displayed to the user.

 

Transformer Helper Strategy

The helper is implemented as an eXtensible Stylesheet Language Transformer (XSLT). This is particularly useful with models that exist as structured markup, such as eXtensible Markup Language (XML), either natively within legacy systems or via some form of conversion. Using this strategy can help to enforce the separation of the model from the view, since much of the view markup must be factored into a separate stylesheet.

The following sequence diagram describes a potential implementation of this strategy:

click to enlarge

The Controller handles the request and invokes a Command object, implemented as a JavaBean Helper. The Command object initiates the retrieval of Account data. The Account object invokes the Business Service, which returns the data in the form of a Value Object (see Value Object pattern), implemented as a JavaBean.

Content retrieval is complete and control is dispatched to the AccountView, which uses its Custom Tag transformer to manipulate the model state. The transformer relies on a StyleSheet, which describes how to transform the model, typically describing how to format it with markup for display to the Client. The StyleSheet is usually retrieved as a static file, though it may also be dynamically generated.

An example of how the Custom Tag Helper might look in AccountView follows:

<xsl:transform model="accounthelper"
stylesheet="/transform/styles/basicaccount.xsl"/>

 

Consequences

  • Improved application partitioning
    Using Helpers results in a cleaner separation of the View from the business processing in an application. The Helpers, in the form of JavaBeans (JSP 1.0) and Custom tags (JSP 1.1+), provide a place to factor out business logic from the JSP. In the JSP, scriptlet code quickly becomes cumbersome and unwieldy in large projects.
  • Improved Role Separation
    Separating formatting logic from application business logic also reduces dependencies that individuals fulfilling different roles might have on the same resources. For example, a software developer might own code that is embedded within HTML markup, while a web-production team member might need to modify page layout and design components that are intermingled with business logic. Neither individual fulfilling these roles may be familiar with the implementation specifics of the other individual's work, thus raising the likelihood of accidental modifications introducing bugs into the system.
  • Reusability
    Business logic that is factored out of a JSP and into JavaBeans and/or Custom Tags may be reused across numerous JSPs. The code is not duplicated in many different JSPs, and thus is easier to maintain and debug. Additionally, since the logic is now removed from the View, the same business logic may be reused, potentially without modification, to service an entirely different user interface, such as a Swing UI.

 

Related Patterns

  • Business Delegate Pattern [SJC]
    The helper components need to access methods in the business service API. It is also important to reduce the coupling among helpers in the presentation tier and among business services in the business tier. It is recommended that a delegate be used because these tiers may be physically distributed across a network. The delegate hides from the client the underlying details of looking up and accessing the business services and it may also provide intermediate caching to reduce network traffic.
  • Service to Worker Pattern [SJC]
    When centralized control becomes desirable to handle such issues as security, workflow management, content retrieval, and navigation, consider using the Service to Worker pattern as an alternative.
  • Dispatcher View Pattern [SJC]
    When centralized control becomes desirable to handle such issues as security and navigation, consider using the Dispatcher View pattern as an alternative.
  • FrontController Pattern [SJC]
    This pattern is paired with the View Helper pattern to create the Dispatcher View Pattern or Service to Worker Pattern.

(c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.

Version 1.0 Beta