日期:2012-08-30 浏览次数:20446 次
1.PHP(&fastm)把文档切割为简单的DOM结构
PHP模板的设计思路非常漂亮,用注释里的Begin和End把HTML(WML,或任何XML)页面切割成不同的块,而且块里面还可以继续切块。
这样一来,一个页面被切割成一个树结构,很象DOM结构。只是DOM结构太过笨重,对每一个元素都要建立一个节点,而且节点的类型非常复杂。比如,一个HTML DOM结构,有多少种HTML元素,就会有多少种节点类型,比如,Body,Table,TR,TD,Form,Input等。
而PHP模板则是一个轻量级的DOM结构,一个Begin-End块就是一个节点。Begin-End块只包括三种内容——静态文本,变量,和其它的Begin-End块。
设计思路如此简洁而强大,易用而通用(可以用在任何规范或不规范的XML页面中,比如HTML,WML,甚至XUL,XAML),而且,能够在HTML编辑器中所见即所得。纵观天下模板技术,莫出其右。
我经过了多种Java页面技术的折磨,经同事介绍,认识了PHP模板技术,欣喜异常,原来竟有这样的好东西,只恨相识太晚。
Fastm模板的思路完全借鉴PHP模板思路,只是稍微做了一些扩展。(详情请参见我的上一篇提到JDynamiTe的文章——Java页面技术综述)。
Fastm模板的BEGIN-END DYNAMIC块,就相当于PHP模板的Begin-End块。
Fastm模板的BEGIN-END IGNORED块,就相当于PHP模板的忽略不显示的Begin-End块。
比如下面的HTML片断。
<select name=”zipcode”>
<!-- BEGIN DYNAMIC: zipcodes -->
<option value=””></option>
<!-- END DYNAMIC: zipcodes -->
</select>
我们看到,这个片断包含一个BEGIN-END块(zipcodes),这个块里包含两个相同的变量,其它的部分都是静态文本。
这个片断的fastm Template DOM结构如下:
静态文本 <select name=”zipcode”>
动态块zipcodes --
| --- 静态文本 <option value=”
| --- 变量
| --- 静态文本 ”>
| --- 变量
| ---静态文本 </option>
静态文本 </select>
2.fastm的ValueSet是DOM概念的又一次飞跃
Fastm模板DOM结构的一个核心特性就是,只能读取,不能改变。
PHP代码每次装载一块PHP模板,然后动态更换里面的变量部分的值。PHP模板从本质上讲是可以读取,也是可以操作改变的。
HTML(WML,XML)DOM更是如此。程序直接修改DOM节点的值,才能得到不同的动态结果。可以说,XML DOM天生就是用来操作改变的。XML DOM本身又是模板,又是数据。
可以改变的DOM结构不能够用在多线程的环境下。每个线程必须获取自己的新鲜DOM备份,进行操作改变,得到自己的动态结果。想想看,在一个静态文本占绝大部分的DOM结构里,这种做法将造成多么大的空间和时间上的浪费。
Fastm模板的DOM结构是只读的,不能改变。所以一个Fastm DOM可以用在多线程的环境中。
既然我们不能改动Fastm Template DOM,那么我们如何给Fastm Template DOM赋值呢?我们如何利用Fastm Template DOM获得动态结果呢?
Fastm引入了ValueSet的概念。ValueSet是一个树形结构的动态数据集,用来匹配只读的Fastm模板DOM结构,生成动态结果。
程序员必须事先构造好整个树形动态数据集(ValueSet DOM),然后把和ValueSet DOM和Fastm Template DOM结合起来,生成动态结果。
所以,fastm的整个使用如下:
(1)程序的整个运行过程中,fastm模板文件(也就是加了BEGIN-END注释的HTML文件)只需要被解析一次,生成一个Fastm Template DOM。
(fastm模板解析速度奇快,比JSP编译,Velocity解析,XML DOM解析,都快很多,大部分情况下甚至快于SAX解析。而且fastm DOM和原始fastm模板文件的大小几乎一样大,只多了一个List记录不同的块,空间效率也要高出)
(2)程序生成不同的ValueSet DOM,匹配只读的Fastm DOM,生成不同的动态结果。
(由于fastm Template DOM结构的简单高效,整个匹配过程很快。通常情况下,时间效率甚至高于最快的纯JSP或Servlet。ValueSet DOM的空间效率比不上纯JSP或Servlet,但经过合理重用,至少可以接近纯JSP或Servlet的空间效率。以后的高级应用话题系列会详细讲解这个问题。)
比如,我们来为上面的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(“”, zipco