1.php(&fastm)把文檔切割為簡單的dom結(jié)構(gòu)
php模板的設(shè)計思路非常漂亮,用注釋里的begin和end把html(wml,或任何xml)頁面切割成不同的塊,而且塊里面還可以繼續(xù)切塊。
這樣一來,一個頁面被切割成一個樹結(jié)構(gòu),很象dom結(jié)構(gòu)。只是dom結(jié)構(gòu)太過笨重,對每一個元素都要建立一個節(jié)點,而且節(jié)點的類型非常復(fù)雜。比如,一個html dom結(jié)構(gòu),有多少種html元素,就會有多少種節(jié)點類型,比如,body,table,tr,td,form,input等。
而php模板則是一個輕量級的dom結(jié)構(gòu),一個begin-end塊就是一個節(jié)點。begin-end塊只包括三種內(nèi)容——靜態(tài)文本,變量,和其它的begin-end塊。
設(shè)計思路如此簡潔而強大,易用而通用(可以用在任何規(guī)范或不規(guī)范的xml頁面中,比如html,wml,甚至xul,xaml),而且,能夠在html編輯器中所見即所得。縱觀天下模板技術(shù),莫出其右。
我經(jīng)過了多種java頁面技術(shù)的折磨,經(jīng)同事介紹,認識了php模板技術(shù),欣喜異常,原來竟有這樣的好東西,只恨相識太晚。
fastm模板的思路完全借鑒php模板思路,只是稍微做了一些擴展。(詳情請參見我的上一篇提到j(luò)dynamite的文章——java頁面技術(shù)綜述)。
fastm模板的begin-end dynamic塊,就相當(dāng)于php模板的begin-end塊。
fastm模板的begin-end ignored塊,就相當(dāng)于php模板的忽略不顯示的begin-end塊。
比如下面的html片斷。
<select name=”zipcode”>
<!-- begin dynamic: zipcodes -->
<option value=””></option>
<!-- end dynamic: zipcodes -->
</select>
我們看到,這個片斷包含一個begin-end塊(zipcodes),這個塊里包含兩個相同的變量,其它的部分都是靜態(tài)文本。
這個片斷的fastm template dom結(jié)構(gòu)如下:
靜態(tài)文本 <select name=”zipcode”>
動態(tài)塊zipcodes --
| --- 靜態(tài)文本 <option value=”
| --- 變量
| --- 靜態(tài)文本 ”>
| --- 變量
| ---靜態(tài)文本 </option>
靜態(tài)文本 </select>
2.fastm的valueset是dom概念的又一次飛躍
fastm模板dom結(jié)構(gòu)的一個核心特性就是,只能讀取,不能改變。
php代碼每次裝載一塊php模板,然后動態(tài)更換里面的變量部分的值。php模板從本質(zhì)上講是可以讀取,也是可以操作改變的。
html(wml,xml)dom更是如此。程序直接修改dom節(jié)點的值,才能得到不同的動態(tài)結(jié)果。可以說,xml dom天生就是用來操作改變的。xml dom本身又是模板,又是數(shù)據(jù)。
可以改變的dom結(jié)構(gòu)不能夠用在多線程的環(huán)境下。每個線程必須獲取自己的新鮮dom備份,進行操作改變,得到自己的動態(tài)結(jié)果。想想看,在一個靜態(tài)文本占絕大部分的dom結(jié)構(gòu)里,這種做法將造成多么大的空間和時間上的浪費。
fastm模板的dom結(jié)構(gòu)是只讀的,不能改變。所以一個fastm dom可以用在多線程的環(huán)境中。
既然我們不能改動fastm template dom,那么我們?nèi)绾谓ofastm template dom賦值呢?我們?nèi)绾卫胒astm template dom獲得動態(tài)結(jié)果呢?
fastm引入了valueset的概念。valueset是一個樹形結(jié)構(gòu)的動態(tài)數(shù)據(jù)集,用來匹配只讀的fastm模板dom結(jié)構(gòu),生成動態(tài)結(jié)果。
程序員必須事先構(gòu)造好整個樹形動態(tài)數(shù)據(jù)集(valueset dom),然后把和valueset dom和fastm template dom結(jié)合起來,生成動態(tài)結(jié)果。
所以,fastm的整個使用如下:
(1)程序的整個運行過程中,fastm模板文件(也就是加了begin-end注釋的html文件)只需要被解析一次,生成一個fastm template dom。
?。╢astm模板解析速度奇快,比jsp編譯,velocity解析,xml dom解析,都快很多,大部分情況下甚至快于sax解析。而且fastm dom和原始fastm模板文件的大小幾乎一樣大,只多了一個list記錄不同的塊,空間效率也要高出)
?。?)程序生成不同的valueset dom,匹配只讀的fastm dom,生成不同的動態(tài)結(jié)果。
?。ㄓ捎趂astm template dom結(jié)構(gòu)的簡單高效,整個匹配過程很快。通常情況下,時間效率甚至高于最快的純jsp或servlet。valueset dom的空間效率比不上純jsp或servlet,但經(jīng)過合理重用,至少可以接近純jsp或servlet的空間效率。以后的高級應(yīng)用話題系列會詳細講解這個問題。)
比如,我們來為上面的template dom結(jié)構(gòu)(zipcode select)構(gòu)造一個valueset dom。
string[] zipcodes = {“361005”, “100008”};
ivalueset top = new valueset(); // 對應(yīng)上面的整個html片斷
list items = new arraylist(); // 對應(yīng) 動態(tài)部分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結(jié)合起來。就生成如下結(jié)果。
<select name=”zipcode”>
<option value=”361005”>361005</option>
<option value=”10008”>100008</option>
</select>
我們可以看到,template dom節(jié)點和valueset dom節(jié)點之間不是一一對應(yīng)的關(guān)系,而是一對多的關(guān)系。一個template dom節(jié)點對應(yīng)一個valueset list。valueset list包含多少個valueset,這個template dom節(jié)點就顯示所少次。
比起taglib來,fastm的優(yōu)勢顯而易見。fastm的幾行代碼,或者一個方法,可以實現(xiàn)一個或幾個taglib的功能。比起任何其它的頁面技術(shù)來說,其它頁面技術(shù)能做到的,或者做的好的,fastm都能夠做得到,而且做的更好。而fastm能做到很多其它頁面技術(shù)做不到的事情。好了。不多說了。j
valueset dom和template dom的分開,是一個極大的思路上的創(chuàng)新和飛躍。
畢竟,頁面中的動態(tài)部分,和靜態(tài)比起來,是非常小的一部分。valueset dom代表動態(tài)部分,由程序隨時生成,可以存在多份。template dom代表靜態(tài)部分,只需要解析一次,而且只需要一份。
valueset dom和template dom的分開,更是一種前所未有徹底的顯示和數(shù)據(jù)的分離。比xml/xslt的方法更加徹底。xml確實是純粹的數(shù)據(jù),但xslt中卻不可避免的要包含邏輯。valueset dom是純粹的數(shù)據(jù),沒有任何邏輯,template dom是純粹的顯示模板,也沒有任何邏輯。
一份template dom可以用多個valueset dom賦值。同樣,一個valueset dom也可以用于多個template dom,把相同的數(shù)據(jù)顯示在不同風(fēng)格的模板中。
比如,我們還有這樣一個html片斷:
<table>
<!-- begin dynamic: zipcodes -->
<tr><td></td></tr>
<!-- end dynamic: zipcodes -->
</table>
我們把上面的top valueset賦給這個模板。得到的結(jié)果如下。
<table>
<tr><td>361005</td></tr>
<tr><td>100008</td></tr>
</table>
我們可以看到,template dom就是模板,只包含顯示風(fēng)格和分塊定義。valueset dom就是數(shù)據(jù),只包含數(shù)據(jù)。
fastm具有其它頁面生成技術(shù)不可比擬的優(yōu)越性:
所見即所得,模板與數(shù)據(jù)的徹底分離,模板與數(shù)據(jù)的多對多自由匹配,易學(xué)易用,開發(fā)速度快,運行空間小,運行速度快。
就我個人的感覺來說,fastm簡直是解決一切頁面技術(shù)問題的銀彈。
上文可能有些“自賣自夸”之嫌,特解釋如下:
我不是一個善于吹噓的人。否則早就從事推銷員、公關(guān)宣傳之類有前途的職業(yè)去了。而且由于自我推銷能力和社會關(guān)系學(xué)能力的欠缺,已經(jīng)造成了自身的能力、精力和時間上的極大浪費。我痛苦自己的現(xiàn)狀,卻不后悔。我了解社會的游戲規(guī)則,但沒有能力,也不愿、不屑參與。內(nèi)心里總是存在著一種癡心妄想,希望創(chuàng)造一個游離于現(xiàn)有規(guī)則之外的奇跡。
另外,我是一個客觀求實、頭腦嚴密清晰的人,具有“外舉不避仇,內(nèi)舉不避子”的負責(zé)的學(xué)術(shù)精神。有一分,當(dāng)說一分,決不多說一分,也絕不少說一分。
3.fastm的可重用性的核心在于valueset dom
jsp技術(shù)的可重用性的核心在于taglib。
xml dom的可重用性的核心在于dom節(jié)點的通用操作。
fastm的可重用性的核心在于valueset dom節(jié)點的通用操作。比如,上面講的那段生成valueset的代碼。
template dom本身可以作為一個只讀模板來使用,同樣,template dom下面包含有的任何template dom結(jié)構(gòu)也可以作為一個獨立的只讀模板來使用。這點和xml dom一樣。xml dom的任何一個節(jié)點可以作為獨立的節(jié)點來使用。
valueset dom不僅是數(shù)據(jù)重用的核心,同樣是模板拼裝重用的中樞。fastm實現(xiàn)各模板之間各個塊的搬運拼裝,再容易不過了。實現(xiàn)所謂的tile功能,小菜一碟。
jsp,還有某些表示邏輯的taglib,velocity模板,xsl文件,都是包含邏輯的模板。個人認為,模板中包含邏輯,是一種很可笑的行為。模板的長處在于表現(xiàn)頁面布局、顯示風(fēng)格,而不在于邏輯。為什么不讓擅長邏輯的java去處理邏輯?
在fastm中,template dom和valueset dom中都不含有任何邏輯。所有的邏輯都落在java代碼中。而java是一種高度面向?qū)ο蟮恼Z言,其結(jié)構(gòu)性和重用性是任何模板語言不能比擬的。所以,fastm的可重用性的核心在于valueset dom節(jié)點的通用操作。這些通用操作的代碼當(dāng)然由java實現(xiàn)。
新聞熱點
疑難解答