MVC的概念已经深入人心,是经常被大家经常提到的法宝利器。
我感到有必要澄清MVC的概念和来龙去脉,以便大家有一个共识,有一个共同讨论的基础,以便能够把讨论更深入地进行下去,解决真正的问题,而不是在一些技术概念上绕圈子。
一般来说,我不喜欢在名词概念上做文章,发表看法和评论。因为有更多的真正有挑战性的问题需要解决。但通过这段时间的讨论,我感到一种这样的危险:
我们程序员是否过于迷信MVC之类的名词概念,是否可能因此而减弱了或丧失了独立思考的能力?
所以我甘冒天下之大不韪,直言不讳了。
先举一个例子。
很多程序员言必讲,“和页面显示相关的逻辑,只应该存在于View里面,而不应该存在于任何其它部分的代码里面。”
但很少有人真正思考,这个概念从何而来。大家隐约地觉得这个概念来自于MVC。但为什么会有这个概念?这个概念的真实来源是什么?
其实,MVC中关于View的原意是这么说的,“View里面只应该存在和显示有关的逻辑,而不应该存在任何其它的逻辑——比如访问数据库,调用业务逻辑之类”。
纠其源头,这是针对很多程序员在JSP中调用JDBC的现象。
大家仔细比较一下这两句话的区别。可以看出对一个概念的执著和崇拜能够达到怎样的一种潜移默化的思维效果。
本意是为了降低View的作用,只让View做这一件事情,不让View做越权的事情。结果成为:只有View才能做这件事情,其它部分没有权利做这件事情。
那么我们来看,所有的MVC框架中,View部分做到了“只和显示逻辑相关” 吗?View能够脱离数据部分单独存在吗?不管是用JSP,Velocity,还是用TagLib,View都必须知道自己所使用的Object的数据结构,必须访问这些Object的各种属性,才能把它们显示出来。这个View和Model分开了吗?能分开吗?
从概念来讲,MVC是一个完备的概念吗?能够自圆其说吗?
Struts是最流行的Web框架,也正是Struts令MVC概念风靡世界,成为Web程序员的圣经。
下面,我们来确认一下什么是MVC和MVC的来龙去脉。
MVC要求,Model把数据填充到request.attribute里面,通过Controller转发,View再把这些数据从 request.attribute里面拽出来显示。
为什么需要这个过程呢?不知道大家想过这个问题吗?更深一步,有没有想过为什么Servlet规范需要request.attribute这个定义呢?
因为你没有别的方式把数据从Model传到View里面去。
MVC是为了解决JSP的天生缺陷而引入(原文为创造,错误) 的。因为JSP是Servlet。你必须请求Web Server帮你定位并调用JSP/Servlet。
你必须调用 request.getRequestDispatcher("your.jsp").include().
既然如此,如何在Servlet之间传输数据?只能通过request.attribute。
Velocity本来和MVC毫无关系,你完全可以在Action里面直接定位调用Velocity Template。
但为了支持MVC,Velocity不得已做了妥协,做了Velocity-tools,来支持MVC。
==========================================================================
Web 表示层开发框架要解决好两方面的问题:
1、表示逻辑与业务逻辑的分离,以便实现细粒度的重用和组件化开发。
解决这个问题不一定非要使用 MVC。我们现在不更新页面时在浏览器/服务器之间传递的全部是 XML 格式的纯数据,与显示格式没有任何关系,显示格式完全由 JS 根据当时的语境自己决定。我认为我们已经很好地实现了表示逻辑与业务逻辑的分离。
2、提供丰富的控件帮助开发人员建造出表现能力丰富的 Rich Client。
这个问题目前各种流行的 Java Web 开发框架做的都是很不够的(可能 Tapestry 能好一些)。为什么?因为设计这些框架的人知识上存在盲区,不知道 JS 能做什么,完全忽视了浏览器端脚本的处理能力。认为所有表示层的问题都可以在服务器端解决掉,因此不需要 JS 的参与。
第二个问题甚至是更重要的问题,解决的难度比第一个问题要大的多。第二个问题不解决好,你就永远无法说服客户你们的产品确实比那个 xx 鸟公司的产品强。
其实一个很简单的 MVC 框架我最多半天时间就可以写出来,呵呵。