Posted on 2007-07-26 16:06
落落 閱讀(1195)
評論(0) 編輯 收藏 所屬分類:
freemarker
基于模板的Web表示層技術 (摘自《Spring開發指南》)
傳統的JSP技術為Web表現層技術提供了靈活、豐富的功能支持。然而,站在工程的角度
而言,過于凌亂的JSP Script也成為系統維護的頭號大敵。
JSP 代碼幾乎等同于Java 代碼,在提供了最豐富的特性支持的同時,也為系統的開發帶
來一些隱患,程序員往往天馬行空,不為羈束,在JSP 中將業務邏輯、數據邏輯、表現邏輯代
碼相混雜,代碼重用性、系統可維護性極低。特別是在參與開發人員眾多,技術水平良莠不齊
的情況下,縱使技術經理一再強調設計規范的約束,但人本的約束總是難以控制,隨著開發過
程進展和產品上線壓力的增大,規范約束逐漸薄弱,于是難以避免的造成代碼的混亂,可維護
性的下降。
面對這個問題,眾多組織和廠商開始研發自己的表現層框架,試圖通過一個隔離的表現層
框架,強行將表現層和邏輯層相剝離。時間似乎退回到了最初Web 端只支持Servlet 技術的
時代(那時候或多或少各個公司都有自己的模板實現)。不過,現在的模板技術經過長時間的
發展,已經將表現層的能力發揮得淋漓盡致,不失為JSP技術之外的一個明智選擇。
模板技術相對傳統JSP技術有以下三個主要優勢:
1. 在技術層面,將表現邏輯與業務邏輯相分離。
2. 為人員之間的分工提供了一個良好的分界點。頁面美工只需專著關心模板的設計,而程序員則專注于業務邏輯的實現。二者重合點明顯減少。
3. 如果需要,模板引擎可脫離Web 容器單獨運行,這為系統可能的移植需求提供了更多的彈性空間(這一特性在應用中也許并不會有太大的實際意義,只是提供了一種附加選擇)。
目前Spring支持一下幾種模板技術:
1. XSLT
XSLT是基于XML的表現層模板技術,伴隨著XML的大量使用。XSLT也日漸成熟,并
迅速成為主流表現層技術之一。XSLT作為一個通用表現層框架,擁有最好的平臺適應性,
幾乎所有的主流程序設計語言都提供了XLST支持,現有的XLST模板可以簡單的移植到不
同的語言平臺,如將J2EE應用中的XSLT移植到.net平臺,這樣的可移植性是其他專用
模板技術,如Velocity和Freemarker難以達到的。
筆者在2001年在一個原型項目中采用了XSLT作為表現層實現,由于當時XSLT尚不
成熟,XSLT解析器效率低下,因此在正式產品開發中使用其他技術作為替代。在2003年
中,經過技術探討,決定再次在項目實施中引入XSLT 技術,相對兩年前,此時的XSLT
技術已經相當成熟,解析器的效率也大大改善。經過半年時間的項目研發,產品上線,并
取得了令人滿意的表現。不過,在之后的項目回顧過程中,筆者認為,目前在項目中大量
采用XSLT技術尚不可取,上述項目開發過程中,XSLT技術提供了極佳的擴展性和重用性,
也保證了業務邏輯和表示邏輯的清晰劃分,然而,最大的問題是,XSLT缺乏強有力的編輯
器支持。雖然通過XML/XSLT 技術成全了設計上近乎完美的表現,但卻為界面開發帶來了
極大難度,以至后期復雜界面的修改都需要消耗極大的人力,得不償失。
筆者在項目開發中所用的XSLT 編輯器為StylusStudio 和XmlSpy,目前這兩款編
輯器可以算是XSLT開發的首選,提供了豐富的特性和可視化編輯功能。但即便如此,XLST
繁雜苛刻的語法和調試上的難度也為開發工作帶來了極大的障礙。
此外,也許是最重要的一點,xslt在性能上的表現尚不盡如人意。經過多年的發展,
XSLT解析/合成器的性能相對最初已經大為改觀,但依然與其他模板技術存在著較大差距。
據實地測試,FreeMarker和Velocity對于同等復雜度的表現層邏輯,平均處理速度是
XSLT 的10 倍以上,這是一個不得不正視的性能溝壑。同時,XSLT 的內存占用也是
FreeMarker 和Velocity 的數倍有余(XSLT 中,每個節點都是一個Java 對象,大量
對象的存儲對內存占用極大,同時大量對象的頻繁創建和銷毀也對JVM 垃圾收集產生了較
大負面影響)。在上述項目中,由于硬件上的充分冗余(8G RAM, 4CPU),才使得這些
性能上的影響相對微弱。
因此,目前在項目中大量引入XSLT技術尚需仔細考量。
2. Velocity
Velocity是Apache Jakarta項目中的一個子項目,它提供了豐富強大的模板功能。
作為目前最為成熟的模板支持實現,Velocity 在諸多項目中得到了廣泛應用,不僅
限于Web 開發,在眾多代碼生成系統中,我們也可以看到Velocity 的身影(如
Hibernate中的代碼生成工具)。
3. FreeMarker
FreeMarker是Velocity之外的另一個模板組件。
與Velocity 相比,FreeMarker 對表現邏輯和業務邏輯的劃分更為嚴格,
Freemarker在模板中不允許對Servlet API進行直接操作(而Velocity可以),
如FreeMarker 中禁止對HttpServletRequest 對象直接訪問(但可以訪問
HttpServletRequest對象中的Attribute)。通過更加嚴格的隔離機制,牽涉邏
輯處理的操作被強制轉移到邏輯層。從而完全保證了層次之間的清晰性。
另外一個Velocity無法實現的特性,也是最具備實際意義的特性:FreeMarker對
JSP Tag提供了良好支持。這一點可能存在一點爭議,JSP技術的最大問題就是容易
在頁面中混入邏輯代碼。而FreeMarker 對JSP Tag 的支持似乎為這個問題又打開
了大門。這一點上,我們可以將FreeMarker看作是僅允許使用TAG的JSP頁面(實
際上,FreeMarker的表達式語法與EL語法也非常類似)。
從開發角度而言,只允許使用TAG的JSP頁面,已經在很大程度上保證了頁面表現邏
輯與業務邏輯的分離。程序員在JSP Script中混雜邏輯代碼的原因,大部分是出于
慵懶,只要無法在頁面模板中直接編寫Java代碼,相信程序員也不會去專門編寫一個
JSP TAG來刻意違反層次劃分原則。
對JSP TAG 的支持為FreeMarker 帶來了極大的活力,目前開源社區中已經有了為
數眾多的成熟Taglib,如DisplayTag、Struts Menu等,這些功能豐富,成熟可
靠的Taglib,將為產品開發提供極大的便利。另一方面,這也為代碼重用提供了另一
個可選途徑,避免了大部分模板實現在這一點上的不足。
就筆者的經驗,對于Web開發而言,FreeMarker在生產效率和學習成本上更具優勢,
而Velocity 的相對優勢在于更多第三方工具的支持和更廣泛的開發和用戶團體(然
而對于一個輕量級模板類庫而言,這樣的優勢并不是十分明顯)。
如果沒有Velocity的技術儲備,而又需要通過技術上的限定解決視圖/模型的劃分問
題,這里推薦采用FreeMarker作為Spring MVC中的表現層實現。以獲得最好的(學
習、開發)成本受益。