Java Web开发构想(2) -- 3.页面资源, 4.页面模板层

时间:2022-09-10 17:10:13

3.页面资源

也许有人会说,页面资源,不就是HTML吗?太简单,太低极了,没劲。DreamweaverFrontpage多简单阿。随便找个人来用就可以了。文本内容乱糟糟不要紧,浏览器里面显示出来的效果好看就行。要增加炫的、酷的动画效果,那就写JavaScript呗。写在HTML里面,看看在IE里面能不能运行就可以了呗。

这也正是大多数公司开发页面资源的方式。因为页面的需求变化是最多、最快的,而页面的制作成本很低,人们不愿意在上面投入更多的资源。

我的看法是,万丈高楼平地起。应用程序的每一个部分都应该完善管理,结构优美。越是需求变化多的地方,越是脏乱差的地方,越应该加大力度处理好。

页面结构方面,Javaeye论坛的Dlee做了很多工作。

(1) 2005 年我们如何写 JavaScript

http://forum.javaeye.com/viewtopic.php?t=12973

[quote="Dlee"]

Ten good practices for writing JavaScript in 2005
http://www.bobbyvandersluis.com/articles/goodpractices.php
在这篇文档中提到的“unobtrusive techniques”是需要高度关注的一种技术。
http://www.kryogenix.org/code/browser/aqlists/

还有这篇:Unobtrusive Javascript
http://www.onlinetools.org/articles/unobtrusivejavascript/
是主要介绍如何以更有效的方式来写 JavaScript 的。

[/quote]

(2)使用 Unordered Lists 制作的下拉菜单和树

http://forum.javaeye.com/viewtopic.php?t=12995

[quote="Dlee"]

Unobtrusive DHTML, and the power of unordered lists
http://www.kryogenix.org/code/browser/aqlists/

我再说一下把页面的 structurepresentation behavior 分离开的意义。一般的人很容易理解把 structure presentation 分离的意义,但是对于为什么需要把 presentation behavior 分离开不是很清楚。
这三部分分离开,页面开发才有可能实现真正的重用,从而最终降低开发和维护的工作量。JS 代码是可以做自动测试的,使用 JsUnit 来做。Web 表示层代码测试困难是公认的,直到今天所有介绍 TDD 的经典教材也没有提出一个好方法。所以我问过一些朋友,都是倾向于不对表示层的代码做自动测试。为什么不做自动测试?没有重用价值的代码值得做自动测试吗?而且我们以前有个误区,认为如果做自动测试,表示层的所有东西都需要测试,其实这个想法是错误的。我们需要做自动测试的仅仅是 behavior 这一部分。以前的测试为什么很困难?就是因为 presentation behavior 没有分离开,我们在 JS 代码中直接操作页面的样式(直接设置元素的 style)。我们不应该再这样做下去,我们应该把 presentation 的工作完全交给 CSS 来做。实现 presentation behavior 的分离有两种方法,通过改变元素的 id 或者使用更通用的方法,通过改变元素的 className。而关于这个 id 或者这个 className 具体的样式在外部的 CSS 文件中设置。JS 文件可以生成新的 structurecreateElementetc.),但是不应该直接改变元素的 style。改变了 style,一切效果你都需要用眼睛看到了才算测试成功,这哪里可以做自动测试?而且假如用户对这个 style 不满意,你还需要去修改 JS 代码。你如果只改变元素的 id 或者 className,做自动测试就要容易得多,你只需要测试最终这个元素的 id 或者 className 是否变成了期望的值。而最终的样式是不是也是你期望的,那是 CSS 文件保证的事情,这只需要在第一次开发 CSS 的时候做一下人工测试就足够了。而这样以来,CSS 文件可以由美工来维护,他完全不需要知道 JS 是什么东西。界面程序员可以去做一些更加重要的事情。

所以在这里我们看到,把 presentation behavior 彻底分离开是做 Web 表示层代码自动测试的关键。把这两部分分离开以后,自动测试的难题就迎刃而解了。再强调一下,只有 behavior 有可能做自动测试,presentation 是不需要也不大可能做自动测试的。

相关资料:
http://www.onlinetools.org/articles/unobtrusivejavascript/cssjsseparation.html

从上面的Dlee的论述和给出的资料。可以看出,页面资源分为三部分:

(1) XHTML。结构,Structure

XHTML里面的Tag部分只应该包括

    等结构布局Tag,或者 表示语义的Tag

    XHTML里面不应该包括风格信息,比如字体、颜色、大小、粗细等,也不应该包括 等字体信息。

    XHTML里面不应该包括Javascript的定义和调用。

    (2) JavaScript。行为,behavior

    JavaScritp应该存在于一个独立于XHTML文件的独立文件中。这样可以做自动化单元测试。JavaScript应该只改变HTML DOM的结构和内容,而不应该改变它的风格。

    (3) CSSStyle,风格。或者说,Presentation,表现。

    前面说了,XHTML里面不应该包括JavaScript的调用。那么,XHTML的元素是如何JavaScript事件绑定起来?就是在CSS里面指定的。

    当然,众所周知,CSS的本职工作是处理页面风格。

    页面资源方面,我完全认同Dlee的观点。从技术和资源积累的长远目标看来,这方面的初期投入的回报将是非常丰厚的。

    即使将来HTML消亡了,进入了XAML, XUL, RSS时代,这些结构清晰的各部分,重用的可能性都非常巨大。JavaScript + CSS + XML UI的这种经典设计思路,将留存很久。混杂成一团的HTML的命运只能是全盘被抛弃。

    4.页面模板层

    页面模板层是指Server端运行的用来生成HTML(或JavaScriptCSS)的Server Side Template Engine

    这一层也是著名的脏乱差楼层。著名的HTMLJava代码污染事件,就发生在这个楼层。不仅JSP有这个问题,其他的template, freemarker, velocity, tapestry等含有逻辑的脚本,都不同程度上有HTMLScript Logic污染问题。

    Dlee的做法很美。直接就不要页面模板层,不用Server Side Template Engine。直接用JavaScript更改HTML DOM的结构、内容、数据。同时,会用到少量的浏览器端XSL

    这样带来的结果,Template就是很干净纯粹的HTML,不含有任何Server Side Script。这个效果,和Servier Side Template JivanXMLC达到的一样。只是一个是在浏览器端执行,一个是在Server端执行。

    我研究比较了几乎所有的Server Side Template Engine,力图采众家之长,避众家之短,写了一个Server Side Template Engine -- fastm, 能够最优雅方便的实现页面模板层。关于fastm,我的Blog上有不少文章论述。

    我的Blog,里面专门有个fastm 分类。

    http://blog.csdn.net/buaawhl 

    http://buaawhl.blogdriver.com

    Fastm发布在java.net上。

    https://fastm.dev.java.net

    我仍然对Server Side Template Engine持肯定态度。基于如下原因:

    (1) JavaScript代码量大、文件多的时候,不容易管理,不容易进行语法检查,不容易跟踪调试。

    这里有人会争辩,Server Side Template Engine也用到了很多脚本阿,比如Freemarker, Velocity, 而且嵌在HTML中,怎么管理,怎么调试?即使是JSP,也是Java Code嵌在HTML里面,怎么管理,怎么调试?

    这里我要说,Jivan, XMLC, fastmWicketTemplate Engine的逻辑都是在Java Code里面。

    (2) JavaScript生成文本内容,搜索引擎不友好。

    一般的网络蜘蛛程序,只根据URL获取HTML文本,搜索里面的文本内容,而不会执行里面的JavaScript脚本。

    (3) JavaScript代码重用还是有些局限

    比如,有两个HTML文件,一个是Table布局,一个是List布局。

    我有同样的一批数据,要在这两种布局中显示。

    这时候,就要给这两个HTML分别写两套JavaScript。这里面的DOM层次,元素,属性都不同,再怎么定义IDClass,也无法用完全相同的一套JavaScript处理。

    这里有人会争辩,Server Side Template Engine也无法做到。别说JSP, Velocity, Freemarker等要在两套HTML里面嵌入相同的代码,就是Jivan, XMLC, Wicket也要分别写不同的两套Java Code,因为它们的XML DOM Node / Model View (Table, List) 都是不同的。

    这里我要说。fastm可以做到只用一套代码逻辑。而且只有fastm可以。fastm的代码重用率是最高的。

    关于Ajax(XMLHttp),我的意见是必要时才用,而且最好采用粗粒度的用法 -- JavaScript发出一个URL请求,返回一整段HTML,直接替换到页面的某一块,而不是用JavaScript来做这样的把数据填充到HTML DOM中。如果你直接在浏览器里面输入那个URL,也可以获取那整段的HTML内容。

    典型的应用场合是PortalPortal页面的每个Portlet都含有这样的 Ajax(XMLHttp) javascript代码 -- 发出一个Portlet URL请求,返回一整段Portlet的内容,直接替换当前的Portlet块。

    这样做的好处是:

    (1) 减少JavaScript代码的量和复杂度。

    (2) 搜索引擎友好。网络蜘蛛程序可以辨别JavaScript中的URL,并根据这个URL,获取整段处理好的HTML文本,进行内容搜索。

    有人可能会争辩:如果URL请求返回的是XML数据,不是整段处理好的HTML,搜索引擎也可以进行内容搜索。

    这点我同意。前提是XML数据的内容是足够连贯的,而不是散落的。比如,你返回的XML数据是“中国”。这个“中国”要放在HTML中的一个{country}位置,{country}足球。这个时候,结果HTML的内容含有“中国足球”。而XML数据中只含有“中国”。如果用户用“中国足球”作为关键字来搜索,就找不到这个URL

    从前面给出的fastm资料的连接中,可以得知。如同Jivan, XMLC, Wicket一样,fastmtemplate里面不含有逻辑,所有的逻辑都写在Java里面。

    有人会争辩说:页面逻辑写在Java里面,我改变了页面逻辑,还需要重新编译。这也太不方便了。Velocity, Freemarker, JSP就不用重新编译。

    这里我的看法是:业务逻辑代码改变了,不也需要重新编译吗?页面逻辑就不是逻辑了吗?HTML里面的脚本怎么语法检查、跟踪调试?业务逻辑需要语法检查、跟踪调试,页面逻辑就不需要语法检查、跟踪调试了吗?

    对方可能会说:在我的应用中,页面逻辑的改动需求非常频繁,而且这些页面逻辑非常简单,不需要语法检查、跟踪调试。

    这里我的意见是:

    (1) 那就使用JSP, Velocity, Freemarker等脚本。

    (2) fastm, Jivan, XMLC, WicketJava代码部分也可以写在脚本里面,比如,Server Side JavaScript, Jython(Python),  Groovy, Bean Shell 等脚本语言都可以很方便的和Java相互调用。

    fastm的生命周期将很长。

    HTML, XUL, XAML都是,或将是可以在浏览器或可视化编辑工具里面显示的XML UI定义语言。Microsoft OfficeWord, Excel, Powerpoint等格式都提供了相应的XML格式。这些XML文件都可以在Office里面显示,并编辑。

    Adobe公司也提供了PDFXML格式 -- XDP。可以在Adobe Designer里面显示并编辑。

    由于fastmDesigner FriendlyXML UI所见即所得的模板技术。这方面具有很大的潜力。

    根本不需要第三方花大力气专门做个IDE,来显示自定义的Tag。目标文件格式提供商自己的阅读编辑工具就可以直接用了,而且效果就是运行后产生的结果文件的效果。

    即使没有可视化要求的场合。比如,Web Service需要的XML数据。fastm同样有用武之地。比如,

      {name}

     

    {name}

    可以很容易的把一个Java Object List转化为XML数据。

    另外,我不得不承认。浏览器端的JavaScript的页面逻辑,可移植性要高于Server Side Template Engine。因为Server Side Template Engine通常是特定语言相关的。

    目前fastm是用Java实现的。由于实现很简单,移植到其它的语言,也很简单。如果是移植到Python, Ruby等动态解释语言,那就更简单了。我是有这个考虑,因为Zope, Ruby on Rails 的模板还是Logic HTML混杂的,fastm这个思路有很大的用武之地。

     前面讲了这么多。清理了两层有名的脏乱差的老大难的楼层 -- 页面资源层和页面模板层。让这两层变得和下面的楼层同样的优雅、清洁。

     下面该讲到Web框架层了。在向下讲之前,由于前面提到了脚本,我想先插入一段关于“可配置”、“可编程”、“可热部署”、“脚本逻辑 vs XML Tag逻辑”的话题。把这个人们比较关心、讨论比较多的话题,先讲清楚。

    posted on 2005-11-01 12:48 Kevin 阅读( ...) 评论( ...) 编辑 收藏