程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 標簽庫,永恆的爭論話題

標簽庫,永恆的爭論話題

編輯:關於JAVA

標簽庫,只是框架的一部分,為了解決頁面顯示數據、封裝簡單頁面邏輯而產生的類HTML標記的組件。

所以千萬不要把標簽的作用神化,也不要認為學習標簽是學習Web框架的重中之重,因為他們只是框架中的小小一部分。

目錄

標簽產生的初衷

標簽,解藥還是毒藥

標簽的發展與趨勢

標簽分類

標簽總攬

標簽產生的初衷

在JSP誕生之初,JSP提供了在HTML代碼中嵌入Java代碼的特性。這種特性使得我們可以比較容易的利用Java這種強類型語言的優勢,完成許多復雜的業務邏輯。

不過隨著時間的推移,我們發現在HTML代碼中嵌入過多的Java代碼,非常不利於JSP的維護和擴展。對於動辄上千行的JSP代碼,很多時候,程序員基本喪失了對JSP的維護能力。基於上述的這個問題,我們嘗試使用一種新的技術,來解決上面這些問題。這也就是標簽產生的初衷:

1. 盡量避免在JSP頁面中使用Java代碼,而改用類似HTML的標簽的形式來表達頁面邏輯,讓邏輯與顯示分離,提高JSP的可維護性

2. 由於HTML自身的標簽的表達能力不足,通過使用JSP Tag,可以對HTML語義進行擴展,從而完成許多HTML自身標簽無法完成的工作

標簽,解藥還是毒藥

有關標簽,爭論一直存在著。早在2004年的時候,robbin同學以一文《炮打Taglib,我的一張大字報!》引起了許多人對Taglib的討論。當時,robbin同學的觀點大概是這樣的:

robbin 寫道

我認為JSP裡面使用Tag,就是一個錯誤!我反對在JSP裡面使用Tag,我推薦大家在JSP裡面寫Java代碼,沒錯,就是在JSP裡面寫Java代碼,我就是一直這麼干!

從Sun在JSP裡面引入Taglib,我就認為他是一個謊言!我認為大家都被Sun欺騙了,我做JSP編程,但凡我寫過的JSP,我從來不用Tag,我覺得寫java代碼讓我很舒服,我不需要再去學習那別扭而無意義的Tag語法,來增加我的工作量,來增加我的JSP頁面調試難度。

不知道時隔快5年,robbin的觀點是否有所變化。在這5年中,JSP的表示層方案實際上並沒有發生很大的變化。Taglib也並沒有消亡,AJAX技術更加蓬勃的發展,模板技術已經被視為成熟並可供使用的重要表示層技術。

標簽,到底是解藥還是毒藥?它到底能不能為View層開發帶來便捷?這個問題,我們需要更加辯證的來看待。我們首先將所有有關標簽的觀點總結成正反兩派:

正方

1. 標簽產生的初衷沒有錯,它的存在,能夠簡化JSP開發的難度,並對HTML的許多標簽進行功能擴展

2. 標簽從效果上的確在一定程度上解決了在JSP頁面中,避免使用Java代碼的情況

3. 由於Java的語法與表現能力上的優勢,使用Taglib能夠極大程度的封裝成塊的HTML代碼,從而形成一套完整的頁面組件,能夠極大的簡化頁面開發

反方

1. 標簽只是為了嘗試避免在JSP頁面中使用Java代碼,實際上,這種情況很難避免。有時候,為了達到這個目的,反而帶來了更多的代碼和沉重的維護成本。一個很簡單的理由,編寫一個Tag,至少需要一個tld文件定義、一個Java的實現類、JSP中去聲明tld並編寫Tag。顯然,對於許多情況而言,這樣所帶來的代碼量,反而超過了在頁面上直接使用Java代碼

2. 不僅如此,標簽的存在為廣大程序員帶來了無窮無盡的學習成本。因為根據使用的框架的不同,會帶來不同的標簽庫。再加上許多公司在標簽庫為基礎的頁面組件方面的積累,公司內部就有一套標簽庫,於是學習這些標簽的語法已經成為了程序員的沉重負擔

3. 對於以標簽庫為基礎的頁面組件,在面對經常變化的頁面邏輯時,顯得無能為力。因為它的維護成本極高,當邏輯變化頻繁時,這些頁面組件的表現能力,還不如直接通過JavaScript操作HTML DOM來的方便

為此,正反雙方也是各執一詞,各有道理。在這點上,JSF是強烈站在正方觀點上的一個Web層框架,它試圖通過IDE的幫助,來解決反方所說的維護成本和學習成本的問題。而許多其他的Web框架,則相對保持中立,對於標簽庫,采取“不拋棄,不放棄”的原則。

如果我們比較理性的來看待這個問題,也只能說,這是一個編程方面的哲學問題。每個人應該根據自己對待代碼的哲學理解進行答案選擇。千萬不要因此而引起框架之爭。

標簽的發展與趨勢

正反雙反的激烈辯論,也推動了View層的發展,因為正反雙方都在尋求對方的破綻,從而找出解決方案反駁。

從正方來講,大約做出了以下的一些進展:

1. 制定標准標簽庫JSTL,試圖統一絕大多數的標簽

2. 借助IDE的幫助,打造更多更豐富的Web層組件,並加強AJAX等功能

3. 將成熟的JavaScript UI框架,改造成Taglib的形式

4. 隨著EL的逐步推廣,在JSP中使用EL也越來越能夠被大家接受

而反方,則大刀闊斧的對View層的表現形式做出了改革,並且被越來越多的程序員所接收:

1. 放棄Taglib,推崇模板技術

2. 不使用Taglib來構造頁面組件,而更多的采用JavaScript技術來豐富頁面展示

3. 直接放棄使用HTML為模式的頁面展現方式,改用Flex等Flash表現方案

從實際效果上來看,反方的方案更加激進,有的干脆直接拋棄了HTML,采取其他的表現形式。使用JavaScript進行頁面渲染的代表應該是Ext,你幾乎無法看到HTML代碼了。而模板技術作為一個新興的技術,也得到了越來越多的程序員的青睐。這幾年以來,富客戶端的發展如火如荼,不知道是不是也能夠成為反方強有利的論據和武器。

而正方,他們所能做的相對比較局限,支持Taglib,無疑就是把Taglib進行擴充,這一點似乎基本上以JSF為首在推基於Taglib的組件,效果如何,自有公論,在這裡我也不做過多的評論了。

標簽分類

在深入探討每個框架的標簽之前,我們先來為標簽分一下類,我們分類的標准,主要是根據標簽的作用。

邏輯控制類

以JSTL為例,JSTL大概提供了以下一些標簽,用於邏輯控制的標簽:

c:if     ———— 分支判斷

c:forEach      ———— 循環

c:choose / c:when / c:otherwise     ———— 分支判斷

c:catch      ———— 異常處理

邏輯控制類的標簽實際上每個框架基本上都有,因為邏輯控制是組成程序的基本要素,可以說,邏輯控制類的標簽在JSP中,也是必不可少的。只是不同的Web框架對邏輯控制類的標簽的定義稍有不同,其本質還是一樣的。

數據輸出類

同樣以JSTL為例,JSTL大概提供了以下幾個用於數據輸出的標簽:

c:out     ———— 輸出表達式的值

c:url     ———— 輸出格式化url

c:set     ———— 設置表達式的值

c:param     ———— 設置參數

fmt:message   ———— 輸出資源文件中的值

fmt:formatDate    ———— 格式化輸出日期

fmt:formatNumber    ———— 格式化輸出日期

數據輸出類的標簽每個框架也都有。比如Struts1中,著名的<bean:property>標簽、webwork中,著名的<ww:property>標簽等等。這些標簽對於JSP頁面來說,也是必不可少的。因為JSP的基本作用就是展現數據,這些標簽正是為了展現數據而提供的。

頁面組件類

頁面組件類的Taglib就更多了,以Struts2為例,Struts2提供了無數UI Tag,具體可以參考:

http://struts.apache.org/2.0.14/docs/tag-reference.html

這些UI Tag實際上是對HTML標簽的擴展和擴充,添加框架本身特有的特性。所以,這類標簽,如果使用得當,將為開發帶來極大的便捷。如果這類標簽使用不當,則會帶來很大的學習成本和維護成本。事實上,這些標簽對於JSP來說,並不是必須的,只是對UI的開發起到輔助的作用。

小結

除了上述這3類Taglib以外,我們還會有很多綜合類的Taglib,這些Taglib往往都是為了解決特定的頁面邏輯或者頁面展示而做出的自定義的標簽。

在我們仔細分析了標簽的分類之後,我們能夠發現,前兩類的標簽實際上對於一個框架和JSP開發而言,是具備價值的,也是必不可缺的元素,而對於後一類的標簽,我們應該謹慎對待。事實上,這些標簽往往可以通過其他的方式代替。我想許多針對標簽的反對的聲音,絕大多數也來自於最自定義的頁面組件標簽的抨擊。如果你在UI的標簽上,表現出了學習上的不適應性,那麼你完全可以思考著采取其他的方案來代替,而不是在一條死胡同裡面。

標簽總攬

首先,我並不想在這裡舉出非常具體的例子來說明每一個標簽中每個屬性的用法,因為這些東西其實大家都可以通過API手冊獲得,我希望列出一些在設計思想上有所差異的標簽種類,並細細品味一下這些Web層標簽的設計初衷和設計思想。

Struts / Webwork

Struts和Webwork的標簽是最傳統的標簽。按照我上面所說的分類,Struts和Webwork基本上在每個分類上都有相應的標簽實現。不僅如此,Struts2還在頁面組件化上下了點功夫,將許多頁面組件定義成了標簽的實現。我個人對Struts2的這種做法持保留態度,因為Taglib畢竟在擴展性和實用性上不如直接使用JavaScript等成熟的框架來的方便。

不過Struts和Webwork的標簽相對來說還是比較好用的,因為它的許多內部實現與HTML自身的標簽屬性非常一致,降低了程序員學習的成本。

JSTL

JSTL也是時下非常流行的一個標簽庫。由於JSTL是Sun力推的標准化標簽庫,所以其剛剛誕生,就奠定了其試圖統一標簽世界的想法。不過實際上,從標簽的分類中,我們也可以看到,JSTL主要實現的內容,是第一類和第二類的標簽,而沒有第三類標簽。按照它的想法,第三類的標簽應該由用戶自己去實現,或者采用其他的替代方案。

JSTL的好處是毋庸置疑的。它會依次從page、request、session、application作用域中查找表達式的值,使得它能夠兼容一切Web框架。因為所有的Web框架基本上還是圍繞著這些Servlet對象來打交道。另外一方面,JSTL的標簽數量比較少,學習成本很低,所以很多程序員都喜歡學習它。

Tapestry

Tapestry的思路與其他Web框架實現標簽的思路全都不同。Tapestry提倡所有的頁面都HTML化,不應引入額外的HTML標簽,如果你需要實現頁面邏輯,應該以組件的形式完成,而這些組件的頁面調用方式,是在HTML標簽中加入一些自定義的屬性。

Html代碼

<table>  
    <tr>  
         <td>User Name</td>  
         <td>Action</td>  
    </tr>  
    <tr jwcid="@Foreach" source="ognl:users" element="tr" value="ognl:user">  
         <td><span jwcid="@Insert" value="ognl:user.name">Quake Wang</span></td>  
         <td><a href="#" jwcid="@ActionLink" listener="ognl:listeners.deleteUser">Delete</a> <a href="#" jwcid="@ActionLink" listener="ognl:listeners.updateUser">Update</a></td>  
    </tr>  
</table>

 

這裡我引用了Quake Wang同學曾經使用過的例子。雖然這個代碼還是Tapestry3時代的代碼,但是我們可以從其中看到許多Tapestry在標簽設計上的獨到之處。它沒有額外的標簽定義,但是有額外的標簽內屬性定義,並通過框架,將這些定義與後台組件聯系在一起。

這或許也就是許多Tapestry程序員對這個Web框架鐘愛的原因,由於沒有額外的JSP標簽定義,那麼頁面展示使用HTML也就夠了。所以,所有的程序員都號稱Tapestry是對美工最友好的Web框架。

我個人對待上述觀點是無法認同的,理由非常簡單,額外定義標簽,與標簽中額外定義屬性,從本質上來說,區別不是很大。從學習成本而言,也陡然增加了程序員學習組件的成本。對於美工呢?他們能忽略這些額外的標簽嘛?理論上,可以,不過如果大家試試看一個比較復雜的帶有多處分支判斷的頁面,美工MM同樣會非常痛苦。

總體來說,Tapestry的標簽具有它的特色,從設計上也有巧思之處。如果我們將這種思想移植到普通的JSP裡面來,其實我們完全也可以使用類似的方式,在HTML標簽中定義額外的屬性,並使用JavaScript來控制這些屬性的行為,同樣可以形成頁面組件。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved