ASP.NET Web Forms vs. MVC
这是一篇早就想写的Blog,之前在CNProg也贴了类似的一个问题,只是一直没有整理好思路,动笔把自己的想法写下来。
自从ASP.NET MVC 1.0正式发布后,基于Microsoft ASP.NET平台的开发方式又多了一个新的选择。MVC不是一个新东西,也不是微软发明的,但是ASP.NET引入MVC框架确实是第一次,而且还大大方方地开源了。经历过从静态网页到动态网页变革 - ASP、PHP、JSP那个混战的年代的朋友,肯定已经对MVC再熟悉不过,特别是使用Java或者PHP等语言的朋友,Structs、Phrame框架以及近两年流行的ROR、Django等,它们都是MVC Web框架的杰出代表。现在,微软也加入了对MVC支持的框架开发,对一向习惯使用Web Forms的ASP.NET开发人员,有些人会兴奋,有些人却开始头疼了。
很多迹象表明微软在发展MVC(以下不作说明,MVC即指ASP.NET MVC框架)同时,会继续ASP.NET Web Forms的支持,这就意味着,至少在接下来的几年里,基于微软的Web开发平台,我们至少有两种不同的ASP.NET开发模式可供选择 - 一种是Web Forms,另一种即是MVC。而这两种开发模式本身的区别,对程序员也有着不同的要求。本文就是要讨论这个令一些ASP.NET开发人员觉得头疼的问题 - 在以后的Web开发中,到底选择Web Forms还是MVC?
语言、平台的选择比较是一个仁者见仁的问题,答案不是简单的是或否。关键在到达那个选择点的之前,我们对要作出抉择的双方了解了多少。所以要回答现在这个问题,我想一个好的方式是通过比较两种模式的特点来得出我们的结论。
起源:页面对象与事件驱动模型 VS. Model-View-Controller
ASP.NET的横空出世,绝对是动态Web开发史上一次创造性的变革。微软把传统桌面应用程序开发的“事件驱动”理念,用到了ASP.NET上面,开发人员理解了ASP.NET的页面对象模型后,可以在Visual Studio里面像编写Windows程序一样,拖拽服务器控件、用户控件来完成Web应用的设计。页面事件的响应以及服务端代码,通过Code-behind代码模型来处理。ASP.NET同时让页面具有了“状态”,它引入了View state的概念,可以保证在Postback的环境下,让页面和控件能够保证维持的数据不被丢失。Postback也是ASP.NET引入的一种通过提交form到服务端实现的和和服务端响应的机制。所有的这一切,微软为我们在HTTP上抽象了一块很大的“蛋糕”,开发人员可以不懂HTTP/HTML,也可以进行ASP.NET的开发任务。
而另一方面,开源社区和其他供应商开始把Model-View-Conroller设计模式引入到Web开发框架之中。MVC分别代表了应用程序的数据,呈现以及如何操作数据和界面的关系,这种典型的架构模式很好地诠释了Web程序使用的场景。而使用这个模型设计的Web框架也具有更为清晰的程序架构,ASP.NET MVC的架构更为直接地在Web程序中,通过编写不同层次的代码来区别Model,View还有Controller的关系。这种架构直接依赖于无状态的HTTP协议之上,让程序员自己可以完全控制数据的输入输出。
页面对象和事件驱动这两个模型是理解Web Forms的核心,可以理解ASP.NET最初这种设计的苦衷,但是作为Web开发人员,绝对不可以不理解HTTP的Request和Response机制,以及HTML和Javascript。在MVC的开发模型下,显而易见地,我们“纠正”了Web Forms的Postback和View state存在的必要性,也避免了它们存在而导致的种种弊端。
发展:测试驱动、低耦合和可扩展性架构
正由于MVC这种松散灵活的架构模式,可以很容易地区分关注点,ASP.NET MVC框架支持TDD的开发方式。而且,MVC的代码都是基于接口(包括基于IHTTPRequest/IHTTPResponse的接口)实现,可以在不运行ASP.NET的前提下,进行单元测试,完全支持不同第三方的单元测试工具。
MVC的设计允许我们对架构进行扩展和接入。比如,我们可以实现自己的视图引擎,地址转发规则等等,而且可以使用IOC容器来进行解耦和优化程序架构。
MVC同时引入了强大的URL Routing组件,能够很方便地设计REST和SEO友好的地址访问。每个地址入口就是一个请求的开始,而不是像Web Forms中需要理解页面和控件的每个事件。
这些特性能够保证在大规模的团队开发模型下,对应用程序的所有层面进行有利的控制。而这些在Web Forms中是有所缺乏的。
争执:我们需要什么样的控件?
Web Forms下面的服务器控件和其他用户控件,围绕事件模型和Postback等机制,为开发人员节省了不少精力去完成这些常见应用的实现。但是在MVC的环境中,每个请求和回馈都是透明的,不再有服务器控件。如果,你已经理解了Web Forms和MVC它们的运行机制的区别,你肯定也能够理解,服务器控件这东西在MVC下面是无法立足的,无需再谈替代方案。
不过,可以看到的是在MVC下,更加容易地使用客户端的控件。无需担心Postback会导致部分数据丢失,也没有Web Forms控件自动生成的“魔法ID“(好消息是ASP.NET4.0会彻底解决这个问题),而且,随着jQuery和众多Javascript类库和控件的流行,客户端在浏览器仍会大放光彩。
如果实在要找替代服务器控件的方案,MVC下面的复用代码将不再是单个控件而已,而是一个个独立的应用程序的接入,我们在前面一个比较中论述了MVC框架这种可扩展性机制的可行性。比如,你正在用MVC开发一个博客程序,为了实现评论功能,你可以直接可以找到一个开源的支持MVC的留言程序,接入你的系统就可以使用了。
共存:Session、模板页、Membership和其他
虽然MVC较Web Forms开发模式有了很大的不同,但是同在ASP.NET这棵大树下,我们需要知道哪些基础功能仍是可以通用的。至少有以下在Web Forms和MVC中可以共存在技术:
- Caching
- Profile和Membership
- Session和Application management
- Configuration
- Forms authentication
- Ajax和jQuery
- Localization
- Master和content pages
而且,在当前1.0版本的MVC下,同一ASP.NET项目可以同时使用MVC和Web Forms。
解脱:自由开放、学习与Hack精神
如果说Web Forms是微软对Web开发人员一个善意的“谎言”,那么MVC则是一次给你“改过自新”的机会。鉴于以上的一些比较,我们在开发一个ASP.NET的应用时候,如果只是完成任务,可能比较过两种开发模式优缺点后,答案也是因地制宜。而某种意义上来讲,MVC是一种更加纯净、开放,给予开发人员更多控制的选择。如果是一名Web开发新手,我推荐采用MVC,在学习的过程中,对于理解HTTP,HTML,Javascript,CSS等基础知识会有着莫大帮助。如果是一名老手,也建议要学用MVC,换个角度看问题,会有新的收获吧。