一个小的WEB项目中的实现方法讨论 - 又一篇[原创]
一个小的WEB项目中的实现方法讨论是2004年10月的一篇帖子,给了我们这些初学者一个很好的提示。
该方法使用command模式,以一个入口servlet作为controller,然后根据request的参数service和target决定调用哪个modle做处理,然后把结果返回到view层target。是一个基本的MVC实现。其controller会根据service参数,使用类的动态加载机制Service service=(Service)serviceClass.newInstance()来实现类似脚本语言的eval()功能来构建动态变量。
深入的分析一下,就会发现以下几个问题:
问题1:随着请求的增加,类的动态加载会造成很大的性能开销,所以这里有必要采取对象池来缓存创建的对象。但这就造成了代码不够简明,加大了学习难度。
问题2:变量target是传给controller供回调时用的,目的是为了把所有页面的跳转都交给controller处理,但一旦modle中的处理出现异常,将不能再返回target指定的页面,这就需要modle给出一个新的返回页面,于是modle层偶尔也要参与页面跳转。
这些问题总觉让人觉得如鲠在喉,虽然做到了MVC的实现,但却不够优雅,甚至牵强。于是我参考了一些资料,结合了以前做c/s软件的思路,本着简化设计的原则,想了以下这种模式来实现系统的设计:
--------------------------------------------------
B/S=统一C的C/S,不要忽视C的处理能力
--------------------------------------------------
1:概念
我们都熟知的MVC理论中,M就是处理业务逻辑的,V就是控制表现的,C就是控制页面跳转的。
一定要这样实现吗?
如果全部都是动态页面,这样的实现是可行和严密的,但如果混杂了静态页面,里边的<a>元素直接定义一个超链接,这样V层直接控制了页面的流向。这就显得不够严密。
这里介绍的概念是:
M=只是处理业务逻辑,并以字符串方式输出最终处理结果。(因为M是V通过script经C验证后调用的,M返回的结果直接就会到了V。)
V=只是处理页面跳转,全部采用静态页面设计,以Ajax或动态加载脚本技术请求V并接收返回值,以脚本在页面处理得到的数据。
C=只是控制V访问M的权限,实现V到M的验证和连接。
更严格的分层如下:
Server层-C+M
Client层-V+Script
这样系统处理的流程就是:
请求V-C-M,返回M-V。
2:实现
以一个Filter充当Controller,将*.do的请求以url方式转向到其他servlet或jsp处理。转向前可做权限检测。
接受转向的servlet全部继承一个接口,此接口实现2种功能,1是verify请求来源是否为Controller,2是execute,并直接将处理结果out.print出来。
V直接得到处理后的结果,并以script表示。
3:优点
A.逻辑严密
所有页面跳转都是V控制的,C只是验证是否有权限访问后台的一个控制器,M根据请求参数做业务处理,并给回返回值。
B.资源耗费最小化
B.1:服务器资源耗费最小化
传统的MVC是通过把数据层层封装,传输到前台以<%=Object.getValue()%>显示,这种MVC是直接取到数据,并以javascript结合DOM在前台动态生成。
传统MVC执行数据库的R操作,服务器的流程是V-C-M-C-V,其中新建数据传输用的临时对象n个。
这种MVC的流程是V-C-M,新建数据传输用的临时对象0个,没有后边的C-V过程。(因为M直接输出结果字符串给V了,V请求的同时就得到了这个结果。M-V的过程不需要后台参与,V的合成是在客户端完成的。)
这样因为M和C都是常驻内存的servlet(C是filter,严格来说不能算是servlet,但也是常驻内存的,jsp本质就是servlet),所以只需要注意线程安全就足够了,线程池一般的容器也都提供,几乎不必使用对象池,对待频繁访问的数据,可以由受到频繁访问的M生成静态文本文件实现cache,节约了大量资源,也简化了编程复杂度。
B.2:网络传输耗费最小化
如果采用Ajax技术,可以实现只传输必要的更新数据,节约大量数据流量。详情请参考Ajax相关资料。
C.服务器平台无关性
因为html和javascript是平台无关的,而对后台的请求得到的都是字符串,我们就可以随意选择后台的运行环境,而不必重新设计V。方便的从jsp-asp-php或其他任何语言中选择。
D.降低学习难度
用这种模式开发WEB站点,jsp/asp/php/等语言,前台编写的难易程度都变成写静态页面的难度了,后台程序员只需要关注自己的后台性能即可。
不论前台还是后台的人员,什么Taglib,什么EL的都不用去看了,甚至连jsp都不需要去学习,只要前台会一点javascript就可以熟练的操作DOM,实现动态更新页面。而后台的程序员也只要控制好各个servlet的访问权限就足够。
E.人员分工合理化
通过使用模板字符替换的技术,可以实现由脚本将数据锚点的内容动态替换成从后台取到的数据,前台美工只需要知道调用哪个url会得到什么结果就可以了,让美工去处理页面的跳转和错误提示信息,这样美工和后台终于可以完全的分割开来。
--------------------------------------------------
正如本文所说,这个构想只是“小”WEB项目的实现方法。大型的企业级分布式应用,我还没接触过。不敢妄加想象。
传统的“推”模式只适合在以前智能终端的年代,那时的客户端处理能力有限,所以是胖Server,瘦Client。
后来客户机的性能逐渐有所提高了,但在WEB方面,Browser的功能还比较单一,所以“推”习惯了的依然在推,CGI把处理好的html推给Browser,Browser只要下载处理好的html,只负责显示就可以了。
到了现在,Browser方面脚本语言的应用早已成熟,我们可以用“拉”模式,仅取出需要的数据,然后在前台合成。实现瘦Server,胖Client,减轻Server的负担。
——不要忽视C的处理能力:C已经吃够现成饭了,不需要S做好了饭菜只管吃了,S只要提供原材料,让C吃自助餐,C会吃的更好!
以上所说由M返回的字符串,可以是一段script代码,也可以是一个xml。具体应用看需求了,如果不是必须,不推荐用xml,因为xml最终也要还原成元数据,倒不如直接写入script来的痛快。构建RSS的时候只需要单独写一个生成RSS的servlet即可。
感谢您看到这里,我刚步入WEB开发行业不久,所学有限,上面的实现方法虽已构思了一段日子,但仍难免考虑不周之处,希望各位朋友看到后能及时斧正。
我喜欢来J道,因为我喜欢Taoism,中国的国教其实是道教,道学是博大精深的。我也敬佩Banq大哥的精神,鄙视一些只是提出批判而没有给出我们其他同道任何有益提示的所谓高手。
祝大家早日得道~
[该贴被s79于2007年03月15日 03:30修改过]