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片断。
我们看到,这个片断包含一个BEGIN-END块(zipcodes),这个块里包含两个相同的变量,其它的部分都是静态文本。
这个片断的fastm Template DOM结构如下:
静态文本
动态块zipcodes --
| --- 静态文本
静态文本
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(“”, zipcodes[i]);
items.add(item);
}
top.setDynamicValueSets(“zipcodes”, items);
我们把top这个ValueSet DOM和Template DOM结合起来。就生成如下结果。
我们可以看到,Template DOM节点和ValueSet DOM节点之间不是一一对应的关系,而是一对多的关系。一个Template DOM节点对应一个ValueSet List。ValueSet List包含多少个ValueSet,这个Template DOM节点就显示所少次。
比起TagLib来,fastm的优势显而易见。fastm的几行代码,或者一个方法,可以实现一个或几个TagLib的功能。比起任何其它的页面技术来说,其它页面技术能做到的,或者做的好的,fastm都能够做得到,而且做的更好。而fastm能做到很多其它页面技术做不到的事情。好了。不多说了。J
ValueSet DOM和Template DOM的分开,是一个极大的思路上的创新和飞跃。
毕竟,页面中的动态部分,和静态比起来,是非常小的一部分。ValueSet DOM代表动态部分,由程序随时生成,可以存在多份。Template DOM代表静态部分,只需要解析一次,而且只需要一份。
ValueSet DOM和Template DOM的分开,更是一种前所未有彻底的显示和数据的分离。比XML/XSLT的方法更加彻底。XML确实是纯粹的数据,但XSLT中却不可避免的要包含逻辑。ValueSet DOM是纯粹的数据,没有任何逻辑,Template DOM是纯粹的显示模板,也没有任何逻辑。
一份Template DOM可以用多个ValueSet DOM赋值。同样,一个ValueSet DOM也可以用于多个Template DOM,把相同的数据显示在不同风格的模板中。
比如,我们还有这样一个HTML片断:
我们把上面的top ValueSet赋给这个模板。得到的结果如下。
361005 |
100008 |
Template DOM は表示スタイルとブロック定義のみを含むテンプレートであることがわかります。 ValueSet DOM はデータであり、データのみが含まれます。
Fastm には他のページ生成テクノロジーに比べて比類のない利点があります:
表示されているものがそのまま得られる、テンプレートとデータの完全な分離、テンプレートとデータの多対多の自由なマッチング、簡単学習して使用するため、開発速度が速く、実行スペースが小さく、実行速度が速いです。
私の個人的な感覚から言えば、fastm はすべてのページの技術的問題を解決する特効薬にすぎません。
上記は少し「自己宣伝」になるかもしれないので、次のように説明します。
私は自慢が得意な人間ではありません。そうでなければ、彼らは長い間セールスマンや広報などの有望なキャリアに従事していたでしょう。さらに、自己宣伝能力や対人関係能力の欠如により、自分自身の能力、エネルギー、時間の多大な浪費を引き起こしています。私は今の状況に苦しんでいますが、後悔はしていません。社会のゲームのルールは理解していますが、参加する能力も意欲も軽蔑する気持ちもありません。私の心の中には、既存のルールにとらわれない奇跡を起こしたいという希望的観測が常にあります。
また、私は客観的で現実的で、厳格で明晰な頭脳を持ち、「外的なことをするときは敵を避けず、内的なことをするときは敵を避ける」という責任ある学問精神を持っています。 。論点がある場合は、その 1 点を言い、決して 1 点以上発言したり、1 点少なく発言したりしないでください。
3. fastm の再利用性の中核は ValueSet DOM
にあります。 JSP テクノロジの再利用性の中核は TagLib にあります。
XML DOM の再利用性の中核は、DOM ノードの共通操作にあります。
Fastm の再利用性の中核は、ValueSet DOM ノードの汎用操作にあります。たとえば、上記の ValueSet を生成するコード。
テンプレート DOM 自体は読み取り専用テンプレートとして使用できます。同様に、テンプレート DOM の下に含まれるテンプレート DOM 構造も、独立した読み取り専用テンプレートとして使用できます。これはXML DOMと同じです。 XML DOM 内の任意のノードを独立したノードとして使用できます。
ValueSet DOM はデータ再利用の中核であるだけでなく、テンプレート アセンブリ再利用のハブでもあります。 Fastm は、テンプレート間での個々のブロックの輸送と組み立てを実現します。これは非常に簡単です。いわゆるタイル機能の実装は簡単です。
JSP、一部の TagLib、Velocity テンプレート、およびロジックを表す XSL ファイルは、すべてロジックを含むテンプレートです。個人的には、テンプレートにロジックを含めるのはばかげていると思います。テンプレートの強みは、ロジックではなく、ページ レイアウトと表示スタイルを表現することにあります。ロジックが得意なJavaにロジックを任せてみてはいかがでしょうか?
fastm では、Template DOM にも ValueSet DOM にもロジックが含まれません。すべてのロジックは Java コードに含まれます。 Java は高度なオブジェクト指向言語であり、その構造と再利用性は他のテンプレート言語に匹敵しません。したがって、fastm の再利用性の中核は、ValueSet DOM ノードの共通操作にあります。これらの一般的な操作のコードは、もちろん Java で実装されます。