视图帮助器
简要说明
业务类变化非常快,而应用程序视图变化更快。业务和表示逻辑之间的耦合使得维护和重复利用非常困难。
“视图帮助器”是一个针对视图进行数据检索的类。它使数据资源适应一个可由应用程序视图使用的简单
API
。“视图帮助器”模式把业务和应用程序类彼此分开,并使它们可以各自改变。这种分离做法还可以提高重复利用率,因为每个业务或表示组件之间几乎不存在依存关系。因此,视图就可以专注于格式化和表示逻辑,并让“视图帮助器”处理数据处理和检索。
详细说明
请参
阅 Core J2EE TM Patterns
(核心
J2EE
™
模式)
。
详细示例
Java
TM
BluePrints Program
对于在浏览器客户上演示的建议是把
JavaServer Pages
TM
(JSP
TM
)
页用作视图组件。实施“视图帮助器”的两个常用策略是
JavaBean
TM
帮助器策略以及自定义标记帮助器策略。
JSP
页提供有助于实施“视图帮助器”的技术:
useBean
标记和自定义标记。
Java Pet Store
网站将一个名为
CatalogHelper
的视图帮助器用作多种视图的视图帮助器。
Java Pet Store
网站还使用
JavaServer PagesTM Standard Tag Library (JSTL)
技术使
CatalogHelper
方法适应
JSP
页的需要。
-
从
JSP
页使用
CatalogHelper
视图帮助器。
类
CatalogHelper
处理和隐藏访问
Java Pet Store
示例应用程序目录的复杂过程,并提供一个连接其客户的简化接口。
CatalogHelper
就是
JavaBean Helper
策略的一个示例。
图
1
中的顺序图显示“视图帮助器”如何代表视图访问数据源。该图中,视图组件是一个
JSP
页类,该类是由
JSP
页编译器从
JSP
页源代码生成的。在此示例中,
JSP
页通过两种方法访问
CatalogHelper
:直接方式,即使用
useBean
标记;以及间接方式,即通过
JSTL
标记。
图 1 :“视图帮助器”模式结构图
示例应用程序视图组件
category.jsp
在含有
useBean
标记的会话作用域内定义
CatalogHelper
的一个实例,如下面的示例所示:
<
jsp:useBean
id
=
"
catalog
"
class
=
"
com.sun.j2ee.blueprints.catalog.client.CatalogHelper
"
scope
=
"
session
"
/>
上面的标记定义类型
CatalogHelper
的一个
HttpSession
属性
catalog
。该页中稍后的标记创建一个称为
pageResults
的变量,该变量是对
CatalogHelper
方法
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
"
/>
上面的标记块初始化用于调用CatalogHelper
方法getProducts
的方法调用参数(通过访问最后一行中的属性catalog.products
)。该标记块然后调用“视图帮助器”对象上的方法,并把结果
页
放在一个名为pageResults
的变量中。CatalogHelper
管理和隐藏以下复杂过程:选择数据源、从数据源获取产品数据以及把这些数据封装为一个页面
对象。以下的代码示例中显示从CatalogDAO
访问数据的代码。
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());
}
}
上面的
DAO
代码直接使用
JDBC
查询获取产品,如下面所示(此代码实际上来自
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 ...
最后,同样是在
products.js
中,以下标记块格式化
Page
对象的内容(该对象由上面的代码创建,并将其保留在会话作用域中)。
JSTL
标记(在
XML
命名空间
c:
中)重复
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>
此示例中理解的关键点是管理数据源选择和数据访问的所有代码都在“视图帮助器”中,而不是在
JSP
页的小脚本中。
同时注意,“视图帮助器”模式可以与其他模式进行组合。例如,“视图帮助器”可以使用
Business Delegate
(业务代理)或
Service Locator
(服务定位程序)帮助管理数据访问。
Java Pet Store
示例应用程序说明如何把与其他模式组合的“视图帮助器”模式用作其总体设计的组成部分。
posted on 2007-01-08 09:08
公主她爹 阅读(198)
评论(0) 编辑 收藏 所属分类:
Java技术