視圖幫助器
簡要說明
業務類變化非???,而應用程序視圖變化更快。業務和表示邏輯之間的耦合使得維護和重復利用非常困難。
“視圖幫助器”是一個針對視圖進行數據檢索的類。它使數據資源適應一個可由應用程序視圖使用的簡單
API
?!耙晥D幫助器”模式把業務和應用程序類彼此分開,并使它們可以各自改變。這種分離做法還可以提高重復利用率,因為每個業務或表示組件之間幾乎不存在依存關系。因此,視圖就可以專注于格式化和表示邏輯,并讓“視圖幫助器”處理數據處理和檢索。
詳細說明
請參
閱 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
的一個實例,如下面的示例所示:





上面的標記定義類型
CatalogHelper
的一個
HttpSession
屬性
catalog
。該頁中稍后的標記創建一個稱為
pageResults
的變量,該變量是對
CatalogHelper
方法
getProducts
調用的結果













上面的標記塊初始化用于調用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 示例應用程序說明如何把與其他模式組合的“視圖幫助器”模式用作其總體設計的組成部分。