|
Guidelines, Patterns, and code for end-to-end Java applications.
 |
|
Java BluePrints > Enterprise > Patterns
View Helper
Brief Description
Business classes change frequently, and application views change
even more frequently. Coupling between business and presentation
logic complicates maintenance and reuse.
A
View Helper is a class that does
data retrieval for the view. It adapts a data resource
to a simple API usable by application views. The View Helper pattern
decouples business and application classes from one another and
allows them to vary at their own rates. Decoupling also promotes
reuse, because each business or presentation component has fewer
dependencies. So the view can focus on formatting and presentation
logic, and let the View Helper handle the processing and retrieval
of data.
Detailed Description
Detailed Example
The Java BluePrints Program recommendation for presentation on browser clients
is to use JavaServer Pages (JSP) pages as view components. Two common strategies for
implementing View Helpers is the JavaBean helper strategy and the
custom tag helper strategy. JSP pages offer technologies that are
useful for implementing View Helper: the
useBean tag and
custom tags. The Java Pet Store website uses a View Helper called
CatalogHelper
as a view helper for
several views. It also uses the JavaServer Pages Standard Tag Library
(JSTL) technology to adapt the
CatalogHelper
methods to the needs of JSP pages.
-
Using the
CatalogHelper View Helper from a JSP page.
The class
CatalogHelper handles and hides the
complexity of accessing the Java Pet Store sample application catalog, and presents
a simplified interface to its clients. The CatalogHelper
is an example of the JavaBean Helper strategy.
- The sequence diagram
in Figure 1 shows how the View Helper accesses a data resource
on behalf of the view. In the diagram, the view component is
a JSP page class, generated from the JSP page source code by
the JSP page compiler. In this example, the JSP page accesses
the
CatalogHelper in two ways: directly,
using the
useBean tag, and indirectly, by way
of JSTL tags.
|
|
Figure 1. Structure diagram of View Helper pattern
|
-
Sample application view component
category.jsp
defines an instance of
CatalogHelper in session
scope with the
useBean tag, as follows:
<jsp:useBean
id="catalog"
class="com.sun.j2ee.blueprints.catalog.client.CatalogHelper"
scope="session"
/>
|
-
The tag above defines an
HttpSession attribute
catalog of type
CatalogHelper.
Later tags in the page create a variable called
pageResults, which is the result of a call to
CatalogHelper method
getProducts:
<c:choose>
<c:when test="${param.count != null}">
<c:set value="${param.start}" target="${catalog}" property="start"/>
<c:set value="${param.count}" target="${catalog}" property="count"/>
</c:when>
<c:otherwise>
<c:set value="0" target="${catalog}" property="start"/>
<c:set value="2" target="${catalog}" property="count"/>
</c:otherwise>
</c:choose>
<c:set value="en_US" target="${catalog}" property="locale"/>
<c:set value="${param.category_id}" target="${catalog}" property="categoryId"/>
<c:set value="${catalog.products}" var="pageResults" />
|
-
The block of tags above initializes method call arguments for the
invocation of
CatalogHelper method
getProducts (by accessing attribute
catalog.products in the last line). It then invokes
the method on the View Helper object, and places the
Page
of results in a variable called
pageResults.
The
CatalogHelper manages and hides the
complex process of selecting a data source,
fetching product data from the data source, and
encapsulating those data as a
Page object.
The code that accesses data from the
CatalogDAO
appears in the
code sample below.
Page getProductsFromDAO(String categoryId, int start, int count, Locale locale)
throws CatalogClientException {
try {
if (dao == null)
dao = CatalogDAOFactory.getDAO();
return dao.getProducts(categoryId, start, count,
locale);
}
catch (CatalogDAOSysException se) {
System.out.println("Exception reading data from dao " + se);
throw new CatalogClientException(se.getMessage());
}
}
|
-
The DAO code above gets the products directly using a JDBC
query, as shown below (this code is actually from
CloudscapeCatalogDAO
):
public Page getProducts(String categoryID, int start,
int count, Locale l)
throws CatalogDAOSysException {
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
Page ret = null;
try {
c = getDataSource().getConnection();
// Select
ps = c.prepareStatement("select a.productid, name, descn "
+ "from (product a join "
+ "product_details b on "
+ "a.productid=b.productid) "
+ "where locale = ? "
+ "and a.catid = ? "
+ "order by name",
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ps.setString(1, l.toString());
ps.setString(2, categoryID);
rs = ps.executeQuery();
// ... and so on ...
|
-
Finally, again in
products.jsp,
the following block of tags formats the
contents of the
Page object (which was created by
the code above, and kept in session scope). The
JSTL tags (in XML namespace
c:) iterate
the
Page collection and extract and
format the catalog product data in the resulting page:
<c:forEach var="item" items="${pageResults.list}" >
<tr>
<td class="petstore_listing">
<c:url value="/product.screen" var="productURL">
<c:param name="product_id" value="${item.id}"/>
</c:url>
<a href='<c:out value="${productURL}"/>'>
<c:out value="${item.name}"/>
</a>
<br>
<c:out value="${item.description}"/>
</td>
</tr>
</c:forEach>
|
The key point to understand in this example is that all of the
code that manages data source selection and data access
is in the View Helper, not in scriptlets in the JSP page.
Also, note that the View Helper pattern may be combined with
other patterns. For example, the View Helper may use a
Business Delegate
or
Service Locator
to help manage the data access. The Java Pet Store sample application
illustrates the use of the View Helper pattern combined
with other patterns as part of its overall design.
|
|