View Helper模式告訴我們,我們能使用Helpers來使得在一個應用中,Model數據能夠適應表現層的需要。典型的,表現層一般都包括一些JSP頁面。這些頁面由一些用來給用戶顯示內容的HTML和圖片組成。然而,當這些頁面需要顯示一些存儲在Model上的動態信息的時候,這里有一個問題出現了。你希望能夠避免在頁面上為了顯示那些動態數據而使用嵌入的Java代碼,你就得使用一些Helper來幫助你實現上述的功能。
要拋棄那些在控制器Servlet里將一些Model數據作為一個屬性存儲在request里面的想法。在一個頁面里,你要獲取Model數據,有三種選擇。你可以以JSP腳本的形式嵌入Java代碼;你也可以使用EL;或者你也可以使用一個Helper幫你取得數據。根據將表現層和商業邏輯分離的原則,使用一些Helper來幫助我們使得數據適應表現層的要求比將表現層代碼和Java代碼混在一起有意義(參見圖1)。

圖1
你可以設想,通過使用簡單易用的Helper代替Java代碼,頁面設計人員開發表現層變得簡單多了。當然,前提是開發人員發布了一個Helper目錄并且詳細描述了這些Helper怎么使用;因為這樣開發人員才會使用那些Helper。然而,如果在開發人員能夠提供使Helper運行起來的Model數據之前,頁面設計人員就已經設計了頁面,就又有新的問題。解決這個問題的一個有用的技巧是在Helper里設置一些假數據以便在沒有Model數據的時候顯示;還有一個可以替代的方法是在Model里設置一些能使Helper運行的假數據。無論哪種方法,頁面設計人員都不會在等待開發人員的時候閑起來。
使用Helper有如下優點:
。表現層的組件是標準化的,為應用提供了統一的look和feel
。Java代碼從頁面設計人員那里被抽離,使得他們有了易用的Helper來訪問Model
。如果Model還不存在的話,你可以創建一些Helper來顯示一些假數據。這樣,不管應用程序的準備如何,頁面設計人員都可以進行他們的設計工作。
。Helper作為業務數據和表現層的中介,它可以把兩者清晰的分離開來。
?
實現JavaBeans Helper的策略
在為JSP頁面開發Helper的時候,你有兩種選擇。你可以使用JavaBeans或者定制標簽,具體選擇哪一種取決于你在Helper中所要處理的數據。一般來說,JavaBeans適合你處理單個的數據,而定制標簽卻更適合使用在那些處理一系列數據的場合。然而,需要著重指出的是,你可以用任意一種方法來處理兩種類型的數據。
實現View Helper模式的策略
你可以在一個JSP頁面里用JavaBeans來實現Helper。當處理和格式化單一的文本數據時,JavaBeans模式的Helper非常簡單易用。那些內置的JSP標簽會讓你非常簡單和直觀的使用JavaBeans。對JavaBeans的使用包括簡單的聲明,后面就可以引用該給定的標簽了,就像下面那樣:
<%-- Declare bean --%>
<jsp:useBean id="myBean" class="jspBook.util.myBean"/>
<%-- Get first name from bean --%>
Hello <jsp:getProperty name="myBean" property="firstName"/>,
welcome to Acme Products' o-nline store!
JavaBeans能做的事可不僅僅是簡單的將數據項從Model里取出來,它還能格式化制定的數據項、進行計算或產生大塊的數據項。如你所想,它非常適合使用內嵌的JSP標簽來獲取數據項。但是如果你使用JavaBeans太多,那么你的JSP頁面將因為太多的Java代碼而變得混亂不堪,不管你使用多少EL。在這種情況下,你應該把所有的附加行為封裝到一個制定標簽里面去。
?
實現定制標簽Helper的策略
為了對付復雜Model的轉換,定制標簽能夠嵌入Java代碼,操作好幾個有關數據的算子,只提供簡單的標簽給頁面設計者使用。為了使用定制標簽,你必須寫一個繼承了TagSupport或BodyTagSupport的類。你可以在標簽庫描述符里聲明你的類,如下所示:
Listing 1. An Example TLD
?
<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
?? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
?? xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
?
web-jsptaglibrary_2_0.xsd"
?? version="2.0" >
?
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>myTags</short-name>
<description>
?? Tag library to support the examples in Chapter 8
</description>
<tag>
?? <name>myTag</name>
?? <tag-class>jspbook.ch08.myTag</tag-class>
?? <body-content>JSP</body-content>
?? <attribute>
????? <name>myAttribute</name>
????? <required>yes</required>
????? </attribute>
</tag>
</taglib>
?
通過在JSP頁面里首先使用taglib指示符聲明以后,這個定制標簽就能夠在頁面里被引用,如下所示:
<%@ taglib uri="/helpers" prefix="helpers" %>
?
<helpers:myTag myAttribute="some value">
?? Body text...
</helpers:myTag>
?
我更傾向于使用定制標簽作為View Helper的實現方式。因為當它們集中存儲在應用服務器的時候,它們給了開發人員更多的訪問Servlet上下文的權限并且提供了更多的性能優點。另一個我傾向于使用定制標簽的原因是它更利于非Java開發人員直觀的使用,它們的格式更像標準的HTML標簽,這些HMTL標簽對于我們大多數的人來說再熟悉不過。最后,一旦這些定制標簽經過了你的開發和測試,你就可以在你的整個項目的所有JSP頁面使用它們。一旦這些定制標簽被設計得更加通用,那么你可以將它們打包起來在所有的項目中使用到它們。
?
實現Model分離的策略
不管是使用定制標簽或者JavaBeans,提供獨立的Helper是非常有用的,這些獨立的Helper能夠在沒有Model數據存在的時候提供一系列的假數據來代替Model數據。這使得頁面開發人員可以獨立于開發團隊而完成它們的任務。為了實現這種策略,Helper需要去檢測Model的存在,以便使用一個真實的Model數據或者使用一個靜態的假Model數據(如下圖)。

按照這個思路,我們需要創建一個靜態的Model來精確復制真實的Model。不是所有的時候都能讓這兩者保持同步。一個在某些時候更完美的替代方法是,讓開發人員創造一些假數據到Model里頭,以便頁面開發人員能夠當作真實Model已經存在一樣;同時也確保了他們自己工作的那個Model永遠是正確的(見圖三)。
?
