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

圖1
你可以設(shè)想,通過使用簡單易用的Helper代替Java代碼,頁面設(shè)計(jì)人員開發(fā)表現(xiàn)層變得簡單多了。當(dāng)然,前提是開發(fā)人員發(fā)布了一個(gè)Helper目錄并且詳細(xì)描述了這些Helper怎么使用;因?yàn)檫@樣開發(fā)人員才會(huì)使用那些Helper。然而,如果在開發(fā)人員能夠提供使Helper運(yùn)行起來的Model數(shù)據(jù)之前,頁面設(shè)計(jì)人員就已經(jīng)設(shè)計(jì)了頁面,就又有新的問題。解決這個(gè)問題的一個(gè)有用的技巧是在Helper里設(shè)置一些假數(shù)據(jù)以便在沒有Model數(shù)據(jù)的時(shí)候顯示;還有一個(gè)可以替代的方法是在Model里設(shè)置一些能使Helper運(yùn)行的假數(shù)據(jù)。無論哪種方法,頁面設(shè)計(jì)人員都不會(huì)在等待開發(fā)人員的時(shí)候閑起來。
使用Helper有如下優(yōu)點(diǎn):
。表現(xiàn)層的組件是標(biāo)準(zhǔn)化的,為應(yīng)用提供了統(tǒng)一的look和feel
。Java代碼從頁面設(shè)計(jì)人員那里被抽離,使得他們有了易用的Helper來訪問Model
。如果Model還不存在的話,你可以創(chuàng)建一些Helper來顯示一些假數(shù)據(jù)。這樣,不管應(yīng)用程序的準(zhǔn)備如何,頁面設(shè)計(jì)人員都可以進(jìn)行他們的設(shè)計(jì)工作。
。Helper作為業(yè)務(wù)數(shù)據(jù)和表現(xiàn)層的中介,它可以把兩者清晰的分離開來。
?
實(shí)現(xiàn)JavaBeans Helper的策略
在為JSP頁面開發(fā)Helper的時(shí)候,你有兩種選擇。你可以使用JavaBeans或者定制標(biāo)簽,具體選擇哪一種取決于你在Helper中所要處理的數(shù)據(jù)。一般來說,JavaBeans適合你處理單個(gè)的數(shù)據(jù),而定制標(biāo)簽卻更適合使用在那些處理一系列數(shù)據(jù)的場合。然而,需要著重指出的是,你可以用任意一種方法來處理兩種類型的數(shù)據(jù)。
實(shí)現(xiàn)View Helper模式的策略
你可以在一個(gè)JSP頁面里用JavaBeans來實(shí)現(xiàn)Helper。當(dāng)處理和格式化單一的文本數(shù)據(jù)時(shí),JavaBeans模式的Helper非常簡單易用。那些內(nèi)置的JSP標(biāo)簽會(huì)讓你非常簡單和直觀的使用JavaBeans。對(duì)JavaBeans的使用包括簡單的聲明,后面就可以引用該給定的標(biāo)簽了,就像下面那樣:
<%-- 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能做的事可不僅僅是簡單的將數(shù)據(jù)項(xiàng)從Model里取出來,它還能格式化制定的數(shù)據(jù)項(xiàng)、進(jìn)行計(jì)算或產(chǎn)生大塊的數(shù)據(jù)項(xiàng)。如你所想,它非常適合使用內(nèi)嵌的JSP標(biāo)簽來獲取數(shù)據(jù)項(xiàng)。但是如果你使用JavaBeans太多,那么你的JSP頁面將因?yàn)樘嗟腏ava代碼而變得混亂不堪,不管你使用多少EL。在這種情況下,你應(yīng)該把所有的附加行為封裝到一個(gè)制定標(biāo)簽里面去。
?
實(shí)現(xiàn)定制標(biāo)簽Helper的策略
為了對(duì)付復(fù)雜Model的轉(zhuǎn)換,定制標(biāo)簽?zāi)軌蚯度隞ava代碼,操作好幾個(gè)有關(guān)數(shù)據(jù)的算子,只提供簡單的標(biāo)簽給頁面設(shè)計(jì)者使用。為了使用定制標(biāo)簽,你必須寫一個(gè)繼承了TagSupport或BodyTagSupport的類。你可以在標(biāo)簽庫描述符里聲明你的類,如下所示:
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指示符聲明以后,這個(gè)定制標(biāo)簽就能夠在頁面里被引用,如下所示:
<%@ taglib uri="/helpers" prefix="helpers" %>
?
<helpers:myTag myAttribute="some value">
?? Body text...
</helpers:myTag>
?
我更傾向于使用定制標(biāo)簽作為View Helper的實(shí)現(xiàn)方式。因?yàn)楫?dāng)它們集中存儲(chǔ)在應(yīng)用服務(wù)器的時(shí)候,它們給了開發(fā)人員更多的訪問Servlet上下文的權(quán)限并且提供了更多的性能優(yōu)點(diǎn)。另一個(gè)我傾向于使用定制標(biāo)簽的原因是它更利于非Java開發(fā)人員直觀的使用,它們的格式更像標(biāo)準(zhǔn)的HTML標(biāo)簽,這些HMTL標(biāo)簽對(duì)于我們大多數(shù)的人來說再熟悉不過。最后,一旦這些定制標(biāo)簽經(jīng)過了你的開發(fā)和測試,你就可以在你的整個(gè)項(xiàng)目的所有JSP頁面使用它們。一旦這些定制標(biāo)簽被設(shè)計(jì)得更加通用,那么你可以將它們打包起來在所有的項(xiàng)目中使用到它們。
?
實(shí)現(xiàn)Model分離的策略
不管是使用定制標(biāo)簽或者JavaBeans,提供獨(dú)立的Helper是非常有用的,這些獨(dú)立的Helper能夠在沒有Model數(shù)據(jù)存在的時(shí)候提供一系列的假數(shù)據(jù)來代替Model數(shù)據(jù)。這使得頁面開發(fā)人員可以獨(dú)立于開發(fā)團(tuán)隊(duì)而完成它們的任務(wù)。為了實(shí)現(xiàn)這種策略,Helper需要去檢測Model的存在,以便使用一個(gè)真實(shí)的Model數(shù)據(jù)或者使用一個(gè)靜態(tài)的假M(fèi)odel數(shù)據(jù)(如下圖)。

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