[翻譯] JSF VS Tapestry 全面比較 <二>
標(biāo)題: JSF VS Tapestry 全面比較 <二>
作者: by Phil Zoio
翻譯: BlueCrystal
來自: http://www.theserverside.com/articl...s?l=JSFTapestry
正文:
Sidebar: 例子程序
在下面本文提供了一個(gè)例子程序,該程序的代碼大部分都將在這片文章中做出詳細(xì)的描述。這個(gè)程序主要就是一個(gè)管理個(gè)人假期的工具,它的主要功能包括:
* 一個(gè)home界面, 列出所有登記的假期,包括假期開始時(shí)間、天數(shù)以及一下描述信息;
* 一個(gè)detail界面,用于瀏覽某一登記假期的詳細(xì)信息;
* 一個(gè)new界面,用于添加一個(gè)假期信息。
下面這幅圖展示了該程序的主體流程和功能:

你可以從下列地址下載該程序基于不同框架的源代碼:
JSF version
Tapestry version
對(duì)比1: 頁面開發(fā)(Page Development)
一個(gè)web應(yīng)用實(shí)際上就是后端用java代碼獲取相應(yīng)數(shù)據(jù),并將數(shù)據(jù)傳遞給前端表現(xiàn)層代碼,然后最終返回給終端用戶。因此,在一個(gè)開發(fā)人員看來,當(dāng)他初次接觸JSF和Tapestry時(shí),最直接的感覺就是JSF的表現(xiàn)層是基于JSP的模板技術(shù),而Ta pestry的表現(xiàn)層模板基本就可以看作是一個(gè)HTML。
JSF
JSF采用JSP的技術(shù)作為其表現(xiàn)層技術(shù)。與標(biāo)準(zhǔn)兼容的JSF實(shí)現(xiàn)必須實(shí)現(xiàn)一個(gè)核心組件的JSP標(biāo)簽集。下面的代碼就是一個(gè)使用了JSF組件標(biāo)簽的Html代碼:
代碼:
<h:form>
<h:panelGrid columns="2" border = "1">
<h:outputText styleClass = "label" value="No"/>
<h:outputText value="#{holidaySession.currentHolidayBooking.holidayID}"/>
<h:outputText styleClass = "label" value="Date"/>
<h:outputText value="#{holidaySession.currentHolidayBooking.date}"/>
<h:outputText styleClass = "label" value="Number of days"/>
<h:outputText value="#{holidaySession.currentHolidayBooking.amount.value}"/>
<h:outputText styleClass = "label" value="Description"/>
<h:outputText value="#{holidaySession.currentHolidayBooking.description}"/>
</h:panelGrid>
<BR>
<h:commandButton value="Back" action="#{holidaydetail_backing.home}" immediate = "true"/>
</h:form>
含有JSF標(biāo)簽的html頁面不能在標(biāo)準(zhǔn)瀏覽器中預(yù)覽。要想瀏覽,必須使用JSF設(shè)計(jì)工具或者直接部署到應(yīng)用中,在真實(shí)運(yùn)行環(huán)境中瀏覽。
對(duì)于JSF技術(shù)來說,其表現(xiàn)層技術(shù)就是JSP,但是這不是唯一的解決方法。Hans Bergsten的文章介紹了可供選擇的其他的方法,讀者可閱讀該文章獲取詳細(xì)信息,Improving JSF by Dumping JSP。 Bergsten的文章中指出了混合JSF和JSP標(biāo)簽暴露出的一些問題。當(dāng)然,這些問題在JSF1.2和JSP2.1中會(huì)得到解決。
Tapestry
對(duì)于大多數(shù)的Tapestry應(yīng)用來說,Tapestry的表現(xiàn)層模板看起來就是一個(gè)簡單的規(guī)則的Html,只不過其中加入了一些Tapestry的屬性。下面是一段例子代碼:
代碼:
<span jwcid = "@Conditional" condition = "ognl:currentHolidayBooking">
<p><strong>Holiday Details</strong></p>
<table>
<tr>
<td class = "label">No</td>
<td><span jwcid = "@Insert"
value = "ognl:currentHolidayBooking.holidayID">1</span>
</td>
</tr>
<tr>
<td class = "label">Start date</td>
<td><span jwcid = "@Insert"
value = "ognl:currentHolidayBooking.date" format = "ognl:dateFormat">1</span>
</td>
</tr>
<tr>
<td class = "label">Number of days</td>
<td><span jwcid = "@Insert"
value = "ognl:currentHolidayBooking.amount.value">1</span>
</td>
</tr>
<tr>
<td class = "label">Description</td>
<td><span jwcid = "@Insert"
value = "ognl:currentHolidayBooking.description">1</span>
</td>
</tr>
</table>
</span>
大家可以嘗試把這段代碼放入一個(gè)Html的body標(biāo)簽當(dāng)中,你會(huì)發(fā)現(xiàn)瀏覽器可以正常的觀看它。
上面的例子中,jwcid = "@componentName"屬性就是定義了一個(gè)Tapestry標(biāo)簽。
Tapestry的模板不僅僅可以用HTML作為載體,它也支持其他的一些標(biāo)記語言,Tapestry標(biāo)簽是具有良好格式的標(biāo)簽,即必須成對(duì)出現(xiàn)。 Tapestry模板技術(shù)支持的標(biāo)記語言典型的就是HTML以及用于無線應(yīng)用的WML。其最大的一個(gè)特點(diǎn) 就是,可脫離Servlet容器,直接預(yù)覽。
事實(shí)上JSF標(biāo)簽由于不是標(biāo)準(zhǔn)的html標(biāo)簽,使得它對(duì)于初學(xué)者來說,是難于使用的。而對(duì)于很多java程序員來說,他們喜歡編輯HTML代碼,至少是樂意編寫html代碼。
JSF技術(shù)宣稱的一個(gè)技術(shù)優(yōu)點(diǎn)就是,可使用同一個(gè)模板編寫運(yùn)行在不同設(shè)備上的應(yīng)用,由此帶來很大的靈活性。然而,這樣做,由于要協(xié)調(diào)不同設(shè)備間的表現(xiàn)差異性,那么很可能同一個(gè)模板,將不能正好表現(xiàn)你的輸出。同時(shí),你不得不學(xué)習(xí)新的標(biāo)簽庫的使用方法,并且搞懂它們是怎樣映射到html的。隨著時(shí)間的推移,JSF標(biāo)簽的簡潔可幫助你很快的編寫表現(xiàn)層代碼,同時(shí)也降低了開發(fā)者對(duì)jsf設(shè)計(jì)工具的依賴。
本文認(rèn)為,JSF的學(xué)習(xí)成本高于其技術(shù)優(yōu)點(diǎn)。在大多數(shù)情況下,我們并不需要編寫適應(yīng)于不同設(shè)備的應(yīng)用。盡管JSF設(shè)計(jì)工具提供了簡單的圖形化的方法來構(gòu)建和預(yù)覽JSF應(yīng)用,但是在一個(gè)開發(fā)中,頁面設(shè)計(jì)人員更多的是喜歡用流行的HTML設(shè)計(jì)工具來編寫和預(yù)覽頁面,這就發(fā)生了一個(gè)沖突,即只有將更多的頁面工作轉(zhuǎn)移到j(luò)ava程序員身上,因?yàn)橐粋€(gè)頁面設(shè)計(jì)人員通常情況下是不樂意去操作JSF設(shè)計(jì)工具的。
JSF開發(fā)者一直在尋找一種解決這些問題的方法。JSF技術(shù)設(shè)計(jì)良好的擴(kuò)展體系,使得這成為可能,其中一個(gè)技術(shù)浮現(xiàn)出來,那就是表現(xiàn)層控制器。一個(gè)非常有前途的表現(xiàn)層控制器的實(shí)現(xiàn)就是Facelets,由java.net創(chuàng)建的開放源代碼項(xiàng)目。Facelets的靈感就來源于Tapestry的模板模型,這使得JSF不再依賴于JSP技術(shù)。Facelets允許開發(fā)者創(chuàng)建Tapestry風(fēng)格的標(biāo)簽,就像下面這段代碼一樣:
代碼:
<input id="bar" type="text" jsfc="h:inputText" value="#{foo.bar}"/>
在未來的一段時(shí)間內(nèi),F(xiàn)acelets將會(huì)被開發(fā)者所采用,或許會(huì)影響JSF未來的版本。
和JSF比較,Tapestry在表現(xiàn)層方面基于HTML代碼,可被標(biāo)準(zhǔn)瀏覽器所瀏覽,這正是它在表現(xiàn)層上的優(yōu)勢(shì)所在。
比較2: java編程模型(Java Programming Model)
在前面我們提到Tapestry和JSF都允許表現(xiàn)層的模板直接和一個(gè)Java類中的屬性和方法進(jìn)行交互,那這些類的實(shí)例在運(yùn)行時(shí)是怎么創(chuàng)建和管理的呢?
Tapestry
Tapestry的一個(gè)完整過程通常都要包括三個(gè)部分:用于顯示的頁面模板(一般就是html),帶有相關(guān)屬性和方法的java類,用于定義頁面模板上的控制元素和java類的關(guān)系的頁面定義文件。Tapestry有著一套特殊的訪問HttpSess ion、ServletContext的體系。
在一個(gè)頁面定義文件中描述所有的數(shù)據(jù)綁定是可以的,但是一個(gè)頁面控制元素卻不能在request周期內(nèi),綁定一個(gè)java類。在request周期內(nèi)只能通過一個(gè)page類訪問一些屬性和方法。這其中最主要的限制就是關(guān)于page類的問題,一個(gè)pag e類必須是BasePage或者AbstractPage的派生類。從另一方面來說,這就意味著你所編寫的表現(xiàn)層邏輯的代碼將會(huì)和框架本身的實(shí)現(xiàn)有著非常緊密的耦合。不過,Tapestry未來的版本就會(huì)減少這種耦合,努力成為一個(gè)松耦合的編程模型。
JSF
在JSF應(yīng)用中沒有頁面定義文件。它只有一個(gè)全局的配置文件,命名為:faces-config.xml,里面通常都定義了一堆"managed beans"。這些managed beans都是帶有屬性和事件監(jiān)聽器的定義良好的java bean。在faces-config.xml中定義的后端bean都有三個(gè)參數(shù):一個(gè)標(biāo)識(shí)符、一個(gè)java類名、一個(gè)bean的生存周期,生存周期可以是request、session、application中的一種。一旦在 faces-config.xml中定義好了一個(gè)managed bean,那一個(gè)前端頁面上的顯示控制元素就可以使用標(biāo)識(shí)符來關(guān)聯(lián)這個(gè)bean。managed bean也可以配置為引用另外一個(gè)managed bean。
JSF和Tapestry都可以方便的與其他的中間層技術(shù)整合,比如Spring。JSF managed bean facility是一個(gè)IoC(Inversion of Control)。通過諸如 JSF-Spring 這樣的擴(kuò)展技術(shù),我們可以方便將其和Spring很好的整合在一起,使得JSF的表達(dá)式可以調(diào)用Spring的bean的方法。雖然Spring可以與 Tapestry3.0整合,但是在Tapestry4.0當(dāng)中才能更好的充分發(fā)揮IoC特性;Tape stry的領(lǐng)導(dǎo)Howard Lewis Ship已經(jīng)在Tapestry啟動(dòng)了IoC框架的工作。Spring的bean將會(huì)很輕松的注入到Tapestry應(yīng)用的類中。
JSF的編程模型提供了更大的靈活型,因?yàn)槟憧梢酝ㄟ^組合的方式來豐富你的代碼功能。比如,你可以設(shè)定一個(gè)指定的managed bean完成頁面的某些功能,同時(shí),你也可以在這些bean里引用其他的managed bena,從而可在頁面間共享一些功能。
而Tapestry必須使用類繼承的方法,也就是說,Tapestry應(yīng)用中的一個(gè)頁面類必須從框架指定的基類中派生(包含一大堆框架指定的狀態(tài)),這并不是一個(gè)理想的方法。
JSF能夠非常直觀的管理session和application周期內(nèi)的狀態(tài): 頁面代碼可以方便的訪問managed bean,而不管其生命周期是request、session還是application。而Tapestry在這方面就相對(duì)差點(diǎn),不過, Tapestry4.0在這方面做了很大的改進(jìn),引入了類似于JSF managed bean的技術(shù),同時(shí),還支持Java 5.0的annotaions技術(shù),減少對(duì)XML配置文件的依賴,從而降低應(yīng)用配置的復(fù)雜性。
JSF在編程模型上來看,與Tapestry相比具有更大的靈活性。