目前,有几种WEB开发的模式:
1、Stream based Template with Script。JSP是典型的这种模式,其核心的对象是HttpServletRequest(接收输入)、HttpServletResponse(显 示输出),是典型的面向Stream的模式,也是最原始的模式。类似的还有Velocity/ASP等。
客观的说,这种模式有一些优点:
1、HTTP的本质是返回一个HTML文本,这是一个字符流。因此,JSP在处理这种模式时,其实是非常自然的,因此,学习曲线相当的平滑。
2、在这种模式下,仍然可以支持一个有限的组件模型,比如说,JSP Tag接口:javax.servlet.jsp.tagext.SimpleTag就可以建立一个SimpleTag /JSPFragement的对象模型,以组件的方式来render内容。
这种面向流式的开发模式主要的问题是在处理输入方面缺乏支持,Stream 主要是处理输出HTML的,但这些输出的东西中有包括着实际在浏览器端客观存在的html组件,这些组件会产生输入,这些输入又会由对应的服务端的逻辑来 进行处理,JSP中的输入/输出是完全脱节的。原始的JSP模式就是在JSP中加入一些 java 代码处理,对请求的处理和对结果的输出是混杂进行的,处理不好导致的就是JSP非常复杂,java代码和html参杂在一起。
Struts试图提供一种MVC2的模式,将对输入的处理转化成为Action的模式,并在独立的Action类中进行处理,这些Action可以在独立的Java类中实现,从而对输入的处理代码可以从jsp文件中剥离出来,在可读性、可维护性上有了提高。
2、Component Based
这样的框架包括:Tapestry、JSF(Facelet)、Echo2、Direct2Dom)等,其设计的思路也各有不同。Tapestry的组件 模型遵循一种无状态的模式,Tapestry中的页面(组件)的模板定义了一个可视化的组件结构,正是这个组件化的结构负责处理输入(让每一个组件更新状 态)和处理输入。由于输入和输出都是由这个组件树中的组件来进行的,因此,对输入/输出的处理可以更好的组件化,并尽可能的模拟一种类似VB的组件模型。
组件可以由属性(这些属性可以跟Model进行绑定从而实现双向更新),也可以由输入出发事件,在相应的事件代码中进行业务逻辑的处理。
JSF与Tapestry类似,不同的是,JSF使用一个更为清晰的6步的生命周期(restore-view, apply-request-value, validating, update model, invoke application, render),而tapestry中,只有render这么一个阶段,对于不同的服务,比如是DirectLink,由服务决定如何控制组件,有的服务 在处理时会安排一个rewind的阶段,在render处理时,可以进行类似的apply-request- value/validating/update mode/invoke application等功能。
JSF的组件模式跟Tapestry不同,JSF的组件模式是有状态的,这个组件树在第一次请求时,根据jsp(facelet使用类似tapestry 的模式)创建view,在后续请求时,则首先恢复上一次的组件树(可以保存在客户端或者服务器端),然后运行生命周期,最后render。在每一个阶段, 尤其是render阶段,都可能重新改变整个组件树。这个改变了的组件树在下一次使用时再次恢复。 Tapestry的组件树则是无状态的,虽然在每次请求时,可以恢复组件的状态,但组件树本身是静态的。
无论是JSF还是Tapestry,他们的组件树只是一种服务器端的组件,跟HTML本身并没有直接的对应关系,而Echo2/Direct2Dom则试 图创建另外的一种模式:Echo组件会产生对应的html代码,这些组件也会有前段的对应的DHTML代码来处理用户的输入,这些输入直接在前端被处理, 然后通过AJAX技术调用服务器,更新服务器端的状态,而对服务器端的状态的修改,可能导致对组件的变化,甚至整个组件树的变化,这种变化又转变成为 Ajax的结果传递给浏览器,在浏览器端再次更新用户界面。
Echo2这样处理的一个结果就是在浏览器和服务器之间建立了一个相同的组件结构,由于是相同的组件结构,输入/输出的处理就更为一致。而Tapestry中对输入的处理仍然会比较复杂(尤其是一些动态的输入组件)。而且由于采用Ajax技术,交互能力更好一些。不过,Echo2目前还依赖于直接使用Java来code用户界面,开发工作量相对较大,如果能够使用HTML作为模板,可能会更好一些。