1.“簡單就是美”空想(響)曲
在軟件設計領域中,有一句膾炙人口的至理名言——簡單即美好。
幾乎所有的軟件設計大師,都會在其著作中訓導讀者:
“簡單即美好”,
“Keep it simple, Stupid”,
“Less is more”,
…..
這是一條耳聞能詳,人人都會說的至理名言。
但實際上,這也是一條被違背得最廣泛、最徹底的至理名言。
“簡單就是美”這個真理就好像天堂一樣,人人都說天堂美好,但人人都拼命拖延到達天堂的時間。
從總體趨勢來講,軟件開發技術總是變得越來越復雜,越來越龐大。
我們來看Java Web表現層技術的發展歷史。
(1)首先,Servlet誕生了。Web程序員們很高興,覺得用起來比CGI爽多了。
(2)過了一段時間,人們就覺得在Java程序里面寫HTML太不爽了。畢竟,在HTML中,靜態的文本標簽占大部分,動態顯示部分只是小部分。不如在HTML里面寫Java代碼。于是,JSP誕生了。成為了ASP的一個有力競爭對手。
(3)過了一段時間,人們又覺得HTML和Java代碼混雜在一起,不僅頁面結構很差,而且其中的Java代碼也很難維護。這就是著名的“Java Code Pollution”問題。不如用自定義的XML元素替換Java代碼,這樣,整個頁面就XML化了。于是,TagLib就出現了。
(4)可還是有一個問題,TagLib不能在一般的HTML瀏覽器或編輯器里面顯示,頁面不能所見即所得。而ASP.net挾Visual Studio快速可視開發之優勢,正在Web開發領域攻城掠地。Java世界倉促應戰,啟動JSF項目。成員眾多的Web Framework陣營中又多出一位權威的重量級選手。
各種新概念層出不窮,頁面流程越來越復雜。
據說這是為了降低開發難度,讓程序員只關注于業務邏輯,而不用關心底層的技術細節;據說這是為了企業級應用,而企業級應用的需求是復雜的,所以,把簡單問題復雜化是有道理的——據說,這是為了系統的面向未來的可擴展性、可伸縮性….
這是個神話廣為流傳的年代,這是個概念批量制造的年代。
深度思索一番,我想,技術的復雜化趨勢,也許是技術市場的商業內需所致?
新技術出現的驅動力一般有兩種:
(1)第一種驅動力是為了解決真正的問題。
比如,Servlet的出現,是為了解決CGI的空間時間消耗問題。較CGI而言,Servlet是一種新思路,一種替代技術。
第一種驅動力來帶來的新技術的產生周期比較長,不足以維持人們對技術的需求。
(2)第二種驅動力是為了彌補前一個技術的不足。
復雜的技術總有一些不足之處,于是為下一次技術革新創造了內需。而且,技術越復雜,不足之處就越多,技術“創新”(或者叫“修補”更合適?)的內需和商機就越大,形成一條自產自銷的技術“修補”產業鏈。
比如,JSP的出現是為了輔助生成Servlet;而TagLib的出現則是為了彌補JSP的不足;TagLib可視化插件則是為了彌補TagLib的不足。商機無限,涌現出一大批提供各種TagLib及TagLib可視插件的技術廠商,技術市場一片繁榮。
這第二種驅動力帶來的新技術的產生周期比較短,而且子子孫孫無窮匱也,絕無斷炊之虞。
但我堅信,技術總有一天要返樸歸真。
總有一天,我們會回到真正解決問題的道路上來,而不是繼續一條技術“修修補補”之路。
2.fastm的誕生——“簡單就是美”王者歸來
Java世界是一個開放的世界。我想,正是因為這一點,廣大的Java程序員才舍不得離開這個Java開發陣營。
java.sun.com公布了所有的java技術規范。
apache.org開源社區吸引了大量的程序員加入Java開發陣營。
sourceforge.net為更廣大的程序員(不僅是Java)提供了交流、共享和發展的空間。
正是因為這樣的開放性,促進了Java開發技術的空前發展。
也正是因為這樣的開放性,形成了Java Web表現層技術群雄逐鹿的局面。
在Java Web表現層技術領域,JSP+TagLib頁面技術是權威,是規范,但這個領域也不排斥其它的技術。
如上所述,JSP+TagLib并不是完美的技術,所以具有不斷改進發展的內在需求。
同時,這一點也促使人們不斷探索、比較其它的技術可能性。
Web表現層之下的所有層次——O/R層、業務層、Web Framework等都直接由Java代碼實現,都能夠很好的結構化,對象化,不存在任何問題。唯獨Web表現層,天生結構松散,野性難馴。
我是一個Java Webapp程序員,一直執著地努力把Web表現層做得具有同樣的結構化,對象化。兩三年來,我應用、研究、比較了多種Web表現層技術:
(1)Velocity http://jakarta.apache.org/velocity/ (and WebMacro, FreeMarker.. etc)
(2)Tapestry http://jakarta.apache.org/tapestry/
(3)Echo http://sourceforge.net/projects/echo
(4)Cocoon (XML + XSLT) http://cocoon.apache.org/
(5)XMLC(Static DOM) http://xmlc.enhydra.org/
(6)NekoHTML (Dynamic DOM) http://www.apache.org/~andyc/neko/doc/html/
(7)JDynamiTe(PHP Template Port)https://sourceforge.net/projects/jdynamite
通過研究比較,我發現了模板技術中的“萬惡之源”——模板里包含的邏輯代碼(if, else, for, 賦值, 操作, 調用等)。
這些包含在模板里的邏輯代碼,是“所見即所得”開發的天敵,也是毀壞重用性的罪魁禍首。
JSP + TagLib,Velocity,Tapestry,XSLT等都是含有邏輯的模板。如果沒有特殊的插件,這些模板都無法正確在普通的HTML瀏覽器或編輯器正確顯示。
而且,混雜在HTML中的邏輯是沒有辦法重用的;你無法把這些邏輯分離出來為通用的方法或類。
JDynamiTe是一個把PHP模板技術移植到Java的一個開源項目。JDynamiTe模板用注釋(BEGIN-END)標記動態塊,用{}標記占位變量。JDynamiTe模板不包含任何邏輯,是“所見即所得”的模板技術,能夠在普通的HTML瀏覽器或編輯器正確顯示。
XMLC等DOM模板技術直接使用HTML文件作為模板,當然也是“所見即所得”的模板技術。
JDynamiTe和XMLC的共同點是,模板中不含有任何邏輯,所有的模板處理邏輯(檢查判斷、節點拼裝、變量替換等)全在代碼中完成。
這兩種技術雖然把邏輯從模板定義中分離了出去,但用法上卻沒有把邏輯和數據從模板中徹底地分離出去。
我們來看XMLC技術中的HTML DOM的用法。一份HTML DOM剛生成的時候,還是一個純潔的模板。但隨后,程序就直接改動HTML DOM的節點數據,甚至改變節點的位置和數量,這份HTML DOM再也不能當作一個純潔的模板重用了,更別說在多線程的環境中被多個線程同時使用了。想想看,在一個靜態文本占絕大部分的DOM結構里,這種做法將造成多么大的空間和時間上的浪費。
JDynamiTe的用法具有和XMLC同樣的性能問題。
我冥思苦想如何解決這種性能上的缺陷,最后,在JDynamiTe、PHP、DOM的思路的基礎上,我創造了Template DOM和ValueSet DOM的概念,從用法上,進一步把數據和邏輯從模板中徹底地分離出去。于是,fastm開源項目誕生了。
3.小、快、簡、易、強的“銀彈”— fastm
fastm具有其它頁面生成技術不可比擬的優越性:
所見即所得,易學易用,開發速度快,運行空間小,運行速度快,模板與數據的徹底分離,模板與數據的多對多自由匹配。
fastm從各方面來說,是最好的模板技術——最快,最小,最易用,最靈活強大(和純Servlet/JSP一樣靈活強大)。我期望fastm這種頁面生成方式,能夠較好地解決Web頁面生成問題,能夠在全世界的Java Web程序員中流行起來。
上面這段話是否只是不自量力的自賣自夸?
這點很容易辨別:fastm是完全開放的一個開源項目,一試便知。由于fastm的思路、實現和用法簡單易懂,這一試也花不了什么時間。
fastm真正地證明了“簡單即美好”。下面我具體講解一下fastm的思路和用法。
3.1 fastm模板是輕量級的DOM
和PHP模板一樣,fastm模板只包含三種元素:
(1)靜態文本。
(2)占位變量。用{}標志。
(3)動態塊。用BEGIN-END DYNAMIC標志。
其中,動態塊可以包含其它的元素——子動態塊,占位變量,靜態文本。所以,fastm模板是一個樹型結構,相當于一個輕量級的DOM結構。后面我們就稱這個結構為Template DOM。
下面舉個簡單的例子。比如下面的HTML片斷。
[code]
<select name=”zipcode”>
<!-- BEGIN DYNAMIC: zipcodes -->
<option value=””></option>
<!-- END DYNAMIC: zipcodes -->
</select>
[/code]
這個片斷包含一個BEGIN-END塊(zipcodes),這個塊里包含兩個相同的變量,其它的部分都是靜態文本。
這個片斷的fastm Template DOM結構如下:
[code]
靜態文本 <select name=”zipcode”>
動態塊zipcodes --
| --- 靜態文本 <option value=”
| --- 變量
| --- 靜態文本 ”>
| --- 變量
| ---靜態文本 </option>
靜態文本 </select>
[/code]
看起來,fastm的Template DOM也沒有什么特殊的。
但Template DOM具有一個至關重要的特性——只讀,不可改變。
既然只讀,那么當然線程安全,同一份Template DOM能夠同時被多個線程并發使用。
那么我們如何從只讀的Template DOM得到動態頁面呢?我們必須把動態數據裝載到一個ValueSet DOM結構(也是一個樹型結構)中,然后用這個ValueSet DOM匹配Template DOM,生成動態結果。
3.2 Template DOM + ValueSet DOM = Dynamic Result
Template DOM包含三種元素節點:靜態文本節點、變量賦值節點、動態塊節點。
由于靜態文本節點不需要賦值,ValueSet DOM只包含兩種元素節點——變量賦值節點,和動態塊賦值節點。其中,動態塊賦值節點可以包含子動態塊賦值節點和變量賦值節點。所以,ValueSet DOM是和Template DOM動態部分對應的一個樹型結構。
Template DOM和ValueSet DOM之間的節點對應關系如下:
Template DOM的變量節點和ValueSet DOM的變量賦值節點之間是一對一的關系。而Template DOM的動態塊節點和ValueSet DOM的動態塊賦值節點之間是一對多的關系,這是為了讓動態塊能夠在頁面中多次顯示。
我們來為上面的Template DOM結構(zipcode Select)構造一個ValueSet DOM。
String[] zipcodes = {“361005”, “100008”};
IValueSet top = new ValueSet(); // 對應上面的整個HTML片斷
List items = new ArrayList(); // 對應 動態部分zipcodes
for(int i = 0; i < zipcodes.length; i++){
IValueSet item = new ValueSet();
item.setVariable(“”, zipcodes[i]);
items.add(item);
}
top.setDynamicValueSets(“zipcodes”, items);
我們把top這個ValueSet DOM和Template DOM結合起來。就生成如下結果。
[code]
<select name=”zipcode”>
<option value=”361005”>361005</option>
<option value=”10008”>100008</option>
</select>
[/code]
一份Template DOM可以匹配多個ValueSet DOM。同樣,一個ValueSet DOM也可以匹配Template DOM,把相同的數據顯示在不同風格的模板中。
比如,我們還有這樣一個HTML片斷:
[code]
<table>
<!-- BEGIN DYNAMIC: zipcodes -->
<tr><td></td></tr>
<!-- END DYNAMIC: zipcodes -->
</table>
[/code]
我們把上面的top ValueSet賦給這個模板。得到的結果如下。
[code]
<table>
<tr><td>361005</td></tr>
<tr><td>100008</td></tr>
</table>
[/code]
我們可以看到,Template DOM就是模板,只包含顯示風格和分塊定義。ValueSet DOM就是數據,只包含數據。
ValueSet DOM和Template DOM的分開,是一個極大的思路上的創新和飛躍。
畢竟,頁面中的動態部分,和靜態比起來,是非常小的一部分。ValueSet DOM代表動態部分,由程序隨時生成,可以存在多份。Template DOM代表靜態部分,只需要解析一次,而且只需要一份。
ValueSet DOM和Template DOM的分開,更是一種前所未有的徹底的顯示和數據的分離。比XML/XSLT的方法更加徹底。XML確實是純粹的數據,但XSLT中卻不可避免的要包含邏輯。ValueSet DOM是純粹的數據,沒有任何邏輯,Template DOM是純粹的顯示模板,也沒有任何邏輯。
由于數據結構是DOM結構, fastm實現Tile,Portal等功能,可以說是Super Easy。你絕沒有必要把頁面組裝邏輯別別扭扭地寫在一堆復雜的TagLib里面,你可以大大方方地把頁面組裝邏輯寫在一個很小的公用方法里面。
3.3 fastm資源列表
http://sourceforge.net/projects/fastm
用戶可以從這個地址下載fastm和fastmweb的源代碼文件、使用文檔。
其中的fastmweb是fastm的輔助項目fastmweb,幫助定義裝載Web環境中的fastm模板。同Velocity一樣,用戶可以在任何web framework中使用fastm模板技術。
http://sourceforge.net/projects/lightweb
lightweb是fastm作者開發的一個輕量級的Web Framework。
其演示程序demo-fastlight演示了如何在lightweb框架中使用fastm,并和jsp程序進行了比較。下載解開之后,可以直接在Web Server(如Tomcat)中運行。
4.技術展望 —— 挽救B/S Webapp?
我確信,fastm一定會作為一種模板開發標準流行起來。
當然,其間必定會遭遇習慣和成見的巨大阻力,畢竟,fastm的作者只是一個名不見經傳的無名之輩。但fastm終會勝出,只是時間早晚而已。
一旦fastm的知名度超過某個閥值,fastm必將以星火燎原之勢攻城掠地,爭奪所有“復雜”模板技術的用戶。
短期來看,fastm消滅了復雜,就等于消滅了大量的商機。fastm本身又如此簡單,提供不了足夠的新的商機;技術作家連寫《fastm in Action》的機會都沒有,因為fastm的定義和用法都太簡單了;而且fastm極大地降低了Java Webapp的技術門檻,是否會令Java Web程序員貶值?fastm對 Java 開發陣營有什么好處?
長期來看,fastm能夠幫助Java開發陣營奪回ASP.net在Web開發領域奪走的領地,改變兩大陣營的力量對比。
fastm足以與Visual Studio.net(ASP)相較,甚至更勝一籌。
fastm模板不需要任何特殊的支持,就能夠在普通瀏覽器中“所見即所得”;ASP模板必須在Visual Studio.net中才能正確顯示(而且是以form的形式顯示)。
fastm模板比ASP模板簡單多了。從用法來說,甚至比其源頭PHP模板還要簡單。使用fastm,大量的PHP程序員可以直接轉到Java Web開發陣營,而不用學習那些龐雜復雜的新模板技術。
JSR-223是一個Java與PHP等腳本語言(還有Perl,Python,Ruby,Tcl)等互操作的JSR。http://www.jcp.org/en/jsr/detail?id=223 目前正處于初稿審定階段。
這從另一個方面說明,fastm生逢其時,直接為Java和PHP程序員提供Java Native的PHP改進模板。
至于fastm是否會令Java Web程序員貶值。我想,可能會讓某些復雜技術的專精高手(比如JSP調試高手,各種TagLib使用高手)貶值。但fastm不會令解決真正問題的高手貶值,相反,fastm會幫助這些高手把精力更集中在解決真正的問題上。
關于目前如火如荼的JSF,我很高興看到這個功能強大的開發框架的出現。
但說實話,我不認為,TagLib可視化拖放開發足以和Visual Studio.net(ASP)競爭。那等于以己之短,較人之長。
而且,一個潛在的危險是,Java Web開發框架將被引上一條微軟倡導的“C/S結構、桌面客戶端”的不歸之路。
目前的一個趨勢是,B/S開發框架盡量向C/S開發框架靠攏。
幾乎所有的現代Web開發框架都在努力地追求著基于事件機制的處理方式——把前臺頁面組件和后臺處理代碼綁定在一起。
Visual Studio.net的ASP開發工具是一個典型的類C/S的B/S開發結構。JSF的Webapp開發工具部分也亦步亦趨,跟著走上了這條路。
不僅在服務端的開發框架存在這種趨勢,在客戶端這種趨勢也愈演愈烈。繼ActiveX,Applet之后, XMLHTTP,FLEX等新一代的“瀏覽器插件客戶端技術”方興未艾。
開源社區Mozilla提出并支持XUL技術。微軟的LongHorn 64位操作系統提出“桌面即瀏覽器”(其實等于宣告瀏覽器的消亡),力推XAML。
HTML不被雙方看好。HTML前景堪憂。
一種可能性:將來HTML很可能只作為一種歷史資料的記錄格式而存在,而不會作為應用程序的UI存在;而HTML瀏覽器也只將作為一種歷史資料查看器而存在;HTML B/S Webapp時代結束。
可以說, B/S Webapp正是毀于自身越來越復雜的內需和開發結構。
B/S Webapp的界面的互操作性要求越來越強,瀏覽器需要支持的特性越來越多,附帶的插件也越來越多(Java Script,ActiveX,Flash,XUL)。既然這樣,為什么還用瀏覽器?Web Service協議比HTTP協議格式更完善,直接用Web Service客戶端不是更直接,更徹底?
微軟把握并引導這個趨勢,Java世界也做好了兩手準備。
無論是Visual Studio.net,還是JSF,其重頭戲都是支持Web Service應用程序開發。畢竟,Web Service是屬于未來兩年的技術。
Web將變得越來越來越強大,無處不在。Semantic Web更有效地把整個Web資源組織為一個巨大的文檔庫、數據庫、資料庫和服務庫。在這個大好形勢下,主角將是各種Web Service Agent,而現在正當紅的主角——HTML B/S Webapp卻面臨著將來(幾年)出局的可能。(呵呵,先別急著說這是危言聳聽,我只是假設這樣的可能性)
傾巢之下,豈有完卵?
如果HTML B/S Webapp消亡了。大量的HTML TagLib就隨之淘汰了。Tapestry,XMLC,Echo也隨之淘汰了。
XML + XSLT的項目也許還能夠幸存——比如,改造XSL,輸出XUL或XAML。
fastm當然也會幸存——fastm也能夠“所見即所得”地生成XUL和XAML。只要有動態生成可視化XML UI的需求,fastm就有用武之地。
如果B/S Webapp注定要退出歷史舞臺,fastm也無力挽救,但fastm至少可以拖延這個過程。fastm極低的技術門檻能夠吸引大量的頁面開發人員,留連在HTML B/S Webapp的領域里。
而且,fastm既屬于現在,又屬于未來。既可以用作構建現在的HTML、WML UI,也可以用于構建將來的XUL、XAML UI。
posted on 2006-03-02 15:12
黑咖啡 閱讀(794)
評論(0) 編輯 收藏 所屬分類:
tec