Why MVC is Better?(翻译)

(本文翻译自CodeProject上的一篇关于ASP.NET MVC的文章,原文地址:http://www.codeproject.com/Articles/821275/Webforms-vs-MVC-and-Why-MVC-is-better。注意文章有些地方出现的”MVC“术语指”ASP.NET MVC“,比如本文标题。本文有助于ASP.NET新手学习基础概念。)

主要内容

  • 前提
  • 介绍
  • ASP.NET Webforms Behind Code的好处和存在的问题
  • 问题1:使用“基于视图”的解决方案去应对“基于行为”的需求
  • 问题2:坏的架构模式带来的副作用:紧耦合
  • 问题3:HTML并不是服务器返回数据的唯一格式
  • 问题4:“视图”与“数据”的灵活组合(这里其实是指MVC的优点,译者注
  • 问题5:将Behind Code代码定义成一个普通类有益于单元测试(这里其实是指MVC的优点,译者注
  • MVC是解决以上问题的有效方案?

来自一个父亲的请求:

谢谢我女儿Sanjana绘制的上面那张图,我很高兴如果你们能够分享脸谱上的这张图片(鉴于我朝不让简单打开,网址略,译者注),因为这会激励她努力成为一个漫画家。我仅仅想让她知道她在绘画这方面多么优秀,所以希望她可以考虑把绘画当做未来的职业目标。

顺便说一下,上面那张图会让你更直观地知道为什么ASP.NET MVC比Webforms好。开头看懂这张图可以帮助你之后将很多东西联系在一起。

前提

这篇文章我将会提到两个比较常见的术语:ASP.NET Webforms和ASP.NET MVC,很多开发者认为ASP.NET不同于MVC,事实上,MVC是一种架构模式,ASP.NET是一个开发框架。如果你是那群认为ASP.NET不同于MVC的人,那么我建议你先阅读这篇文章http://computerauthor.blogspot.in/2014/08/aspnet-vs-mvc-vocabulary-confusion_15.html

介绍

如果你看了最近微软公司的议事日程,你会发现他们一直把焦点放在了MVC之上。那么为什么微软热衷于去推翻一个本来已经很成功的产品(如ASP.NET Webforms)而极力建议开发社区的开发者们转向使用ASP.NET MVC呢?

这就是本篇文章着重要讲到的内容。

ASP.NET Webforms Behind Code的好处和存在的问题

ASP.NET Webforms是一个RAD/VISUAL(快速可视化)的Web程序开发技术。也就是说,开发者简单地拖拽控件到窗体设计器上,VS就会在Behind Code(aspx.cs文件,译者注)生成代码。

换句话说,你向设计器中拖放一个Button按钮后,便可以在它的事件处理程序中编写代码了。

Behind Code文件就是开发者能够快速开发Webforms程序的关键,因为它封装了底层复杂的技术过程,如event、delegates、HTTP协议Post、Get以及Session管理等等。你可以阅读这篇博客Why Microsoft has partial classes虽然本文反对者居多,但是我觉得还是有一些道理,译者注),了解微软在UI设计方面取得成功的故事。

但正是Behind Code的工作方式给开发Web程序带来了5个严重问题,下面我们来讨论一下这5个问题以及MVC是怎样解决这些问题的。

问题1:使用“基于视图”的解决方案去应对“基于行为”的需求

Web网站最终是给终端用户使用的,终端用户带着特定的目的去访问一个网站,然后他们使用一些“行为动作”(比如输入URL、点击提交按钮等等,译者注)来表达他们想要干什么。比如一个人去购物网站购物,那么他会通过以下行为来表达他想干什么:

  • 买东西
  • 打印发票

以上这些行为就会通过类似点击按钮、右键或者在浏览器地址栏中输入URL来完成。正是因为以上这些行为的构成特点,所以Web程序选择使用HTTP协议,因为该协议包含了许多与之相似的动作诸如POST、GET、PUT以及DELETE等等,这些恰恰能更形象地表达终端用户的意图。这样很自然地,我们要是能够把用户的这些行为一一映射到我们程序方法(函数)上,这不仅会更有意义还会使项目架构更加清晰明了。

但是,微软无法这样去做。因为微软一直想推广它的“快速应用程序开发”(RAD)的概念(或者我们也可以称之为“可视化编程”),所以它最终选择了一个“基于视图”的解决方案去应对“基于行为”的需求。

如上图所示,用户的“请求过程”呈现出一个古怪的路线(见上图)。

  • 终端用户通过POST/GET方式发送一个Request请求
  • IIS服务器将该请求转到对应的视图(Page页面,译者注
  • 视图初始化一个页面,开始页面生命周期,激发对应事件(Page.Load,译者注),最终处理终端用户的行为三层架构中,就是调用业务逻辑成、数据访问层进行处理,译者注
  • 最终服务器将结果以HTML的形式Response给终端用户的浏览器

如上,微软搞出了一个“基于视图”的架构方案去应付一个“基于行为”的需求。换句话说,如果一个终端用户发出了一个“购买”的请求,那么该请求先被一个类似“Shopping.aspx”的页面进行处理,然后该页面再去通知类似“Shopping.aspx.cs”,接着开始一个复杂的页面生命周期,最后激发对应事件(Page.Load,Button.Click)进行请求处理然后将结果返回给终端用户。

上面这个过程相当复杂繁琐,终端用户的任何一个请求都是需要先经过一个复杂的页面生命周期之后才能真正被处理。那么,我们创建一个“面向行为”的架构方案去取代“面向视图”怎么样?

如果我们先处理请求,然后再呈现视图给终端用户,这个流程是不是要更清楚明了一些呢?事实上,MVC就是这样做的,用户请求先被对应的Controller处理,然后再由后者呈现对应的View(附带Model)。

问题2:坏的架构模式带来的副作用:紧耦合

一旦你选择了一个下三滥的架构模式,你后期会为了适应它而不断地做出妥协,最终出现越来越多的负面效果。ASP.NET Webforms恰恰就是这样的。Behind Code(aspx.cs文件,译者注)从来都不会真正地符合“松耦合”的规则,比如ASPX.CS文件永远不能与ASPX文件分离开来。

换句话说,我们不能轻易地将“Customer.aspx.cs”和“CustomerDetailed.aspx”组合到一起,Behind Code和视图仅仅关联在一起,不能被复用。

如果你比较过Behind Code代码和项目中其它模块代码,你会发现前者不但体积庞大而且还充斥着不计其数的事件处理程序代码。这不仅使代码不易阅读,后期维护更是难上加难。

如果我们将“视图优先”的架构方案换成“行为优先”的方案,我们就很容易地重用一部分逻辑代码,并且呈现给最终用户的视图可以随意切换。比如,如果一个终端用户发送一个“Display”的请求,那么我们可以选择将“DisplayDesktop.aspx”或者“DisplayMobile.aspx”发送给终端用户,而这完全取决于用户当前使用设备。

在MVC中,我们可以很轻松决定到底显示“MobileView”还是“NormalView”,你可以想象,在Webforms中,实现这个是多么复杂。

问题3HTML并不是服务器返回数据的唯一格式

在Webforms中,视图和Behind Code不仅处于一种“紧耦合”状态,就连服务器返回的数据格式也是相当固定的,默认为HTML。如果你想要改变返回数据的格式,那么你得和Content-Type以及Response.End方法打交道了,这是一件多么头疼的事情。

事实上,如果我们使用“行为优先”的方案,在处理完用户请求后,就有很大机会去决定到底给用户返回什么格式的数据。下面是一段MVC根据传进来的参数来决定到底返回JSON还是HTML给用户的代码。这种灵活性在Webforms中几乎很难实现。

问题4:“视图”与“数据”的灵活组合(这里其实是指MVC的优点,译者注

当我们给用户一个Response时,其实包含View和Data两部分(View代表页面结构,Data代表页面数据,译者注)。Webforms是一个“视图优先”的架构模式,所以它很难灵活地切换最终呈现给用户的视图,不断如此,视图还要负责调用逻辑处理的代码,这完全违背了单一职责原则(SRP)(详细的SOLID五大设计原则请参见博主前面博客,译者注)。

如果我们使用“行为优先”的架构模式,那么当请求到达时,先经过处理,再才决定呈现给用户什么视图和数据。

MVC中,在处理请求时,你可以编写如下代码。你可以将同一个Model(数据,译者注)与不同的View进行组合。如下面代码中所示,你可以将一个Model(customerdata)与一个View(DetailCustomer)组合,也可以将它与另一个View(Customer)组合。

这种灵活性在Webforms中是非常难以实现的,因为在Webforms中,请求先到达视图(Page页面,译者注),然后由它决定调用什么处理逻辑。视图在一开始就决定死了。

问题5:将Behind Code代码定义成一个普通类有利于单元测试(这里其实是指MVC的优点,译者注)

在Webforms中,Behind Code代码以一个Partial类的形式出现,它相当复杂(继承自Page类),而且不能轻易地创建它的实例。默认情况下,每个页面均继承自Page类,由于Page类依赖项比较多,所以实例化一个Web页面对象相当困难(这里指单元测试的时候,译者注)。

现在你可能会问,为什么你要自己实例化一个Page类对象?原因很简单,因为我要进行单元测试,我要测试按钮Button1的Click事件处理程序(Button1_Click)是否按照我的预期那样去执行。

但是问题来了,如果你按照以下方式去编写测试代码,它会抛出异常

这使得UI这块的单元测试非常困难:

在MVC中,Behind Code变成了简单正常的类(Controller中的各种Class,译者注),创建这些类实例没有之前那么费劲。

MVC是解决以上问题的有效方案?

将“基于视图”的架构转变为“基于行为”的架构,我们需要做以下几个修改(见上图):

  • 将原来所有的Behind Code(aspx.cs文件)中的代码定义成MVC中Controller中的类,并将原来的事件处理程序改成一系列常规方法(我们可以称之为Action)
  • 原来三层架构中的“中间层(BLL)”变成了现在的Model,它负责提供数据以及一些逻辑处理
  • View仅仅负责显示,比如页面HTML元素的位置、布局等
  • 原来三层架构中的数据访问层(DAL)不需要做太多的改变,因为原本Behind Code就很少与它打交道

那么,使用MVC架构后,

  • 终端用户发送它的请求到Web服务器,服务器将其路由给指定的Controller
  • Controller找到一个对应的Action进行处理
  • 现在,Action有两件事要做,第一根据需要访问Model获取数据,然后再将获取的数据传递给合适的View,最终将View发送给终端用户的浏览器

ASP.NET Webforms最大的优势就是RAD和VISUAL(快速可视化开发),即使现在看来它是那样的繁琐和不堪入目,但它确实能够让你的程序开发速度加快,准时完工(不考虑其他后果,译者注)。

在2000年,微软推出ASP.NET Webforms是一个正确的决定,因为那时候它想吸引那些已经熟悉VB6、VF、VC++等快速开发技术的开发人员,我认为Webforms已经达到了它原来的目的。现在我们是时候迈开脚步去学习更好的架构模式了,比如MVC(对应的ASP.NET MVC,译者注)。

---------------------------

以上为翻译全文,斜体字为译者自行增加的内容。全文并没有一字一句的按照原文翻译,部分属于译者自己理解而写出来的。能力有限,翻译不当之处望海涵。

时间: 2024-11-09 10:18:11

Why MVC is Better?(翻译)的相关文章

Webform和MVC,为什么MVC更好一些?

前言 如果你看了最近微软的议程,你会发现他们现在的焦点除了MVC,还是MVC.问题在于为什么微软如此热衷于丢弃传统的ASP.NET Webform而转向ASP.NET MVC?本文就主要来讨论这个问题. ASP.NET Webform 后台代码(behind code)—— 福音与诅咒 如果你密切关注过ASP.NET Webform技术,你会发现它更接近可视化设计,换句话说,开发者只需要从设计面板中拖拽控件即可完成UI,接着在behind code中实现逻辑代码即可完成最后的Web页面功能. 所

Dojo教程翻译索引

Getting Started Dojo Start 原文 翻译 Hello Dojo!原文 翻译 Modern Dojo 原文 翻译 Configuring Dojo with dojoConfig 原文 翻译 Fundamentals Classy JavaScript with dojo/_base/declare 原文 翻译 Creating Templte-based Widgets 原文 翻译 Using dojo/query 原文 翻译 NodeList Extensions 原文

MVC比WebForm的优势,为什么使用MVC

前言 如果你看了最近微软的议程,你会发现他们现在的焦点除了MVC,还是MVC.问题在于为什么微软如此热衷于丢弃传统的APS.NET Webform而转向ASP.NET MVC?本文就主要来讨论这个问题. ASP.NET Webform 后台代码(behind code)—— 福音与诅咒 如果你密切关注过ASP.NET Webform技术,你会发现它更接近可视化设计,换句话说,开发者只需要从设计面板中拖拽控件即可完成UI,接着在behind code中实现逻辑代码即可完成最后的Web页面功能. 所

最省力的多语言解决方案

微软的ASP.NET localization(本地化,多语言)的方案,在使用的过程中,碰到许多的问题,这些问题都不是技术实现上的.主要是他浪费了我们许多的时间和精力. 1.在页面上使用许多key来替换页面的汉字文本,导致页面不可读,很难定位,维护困难. 2.要把全部的文本换成key,工作量巨大,繁重枯燥,很容易出错,忘记转换,忘记后很难发现. 3.key很容易发生冗余,因为不同时间加入的文字到底以前加过没有,要查找,挺烦的, 4.key和文本的一致性不好维护, 最近在开发了几天和python

ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第一章:创建基本的MVC Web站点

在这一章中,我们将学习如何使用基架快速搭建和运行一个简单的Microsoft ASP.NET MVC Web站点.在我们马上投入学习和编码之前,我们首先了解一些有关ASP.NET MVC和Entity Framework的背景信息,然后再详细学习如何搭建开发环境. 1.1 MVC和ASP.NET MVC 这本书涵盖Microsoft版本的MVC,即ASP.NET MVC.在写本书的时候,ASP.NET MVC的生产版本为MVC5,因此,本书的示例代码都使用ASP.NET MVC 5编写.在本书中

【原创翻译】认识MVC设计模式:web应用开放的基础(基础篇)

原文地址:http://www.larryullman.com/2009/10/08/understanding-mvc/ 翻译:shadowmydx 转帖请注明 最近,我计划写一个系列关于自己在过去几个月使用的Yii框架(shadowmydx:基于PHP5的一个web开发 框架,详情自行google)的文章.但在一切开始以前,我认为首先还是需要先介绍一下MVC设计模式: 模型-视图-控制器.MVC模式(30年前就有鸟)已经成为了框架以及许多各式各样的应用的首选.MVC模 式主要着眼于分离应用的

WebForms VS. MVC(翻译)

原文:WebForms VS. MVC(翻译) (本文翻译自CodeProject上阿三写的一篇文章,原文地址:http://www.codeproject.com/Articles/528117/WebForms-vs-MVC,讲了有关ASP.ASP.NET WebForms以及ASP.NET MVC三种技术,这篇文章有助于ASP.NET初学者理解一些基本概念.) 介绍: 我很早之前就开始从事Asp.NET的开发工作,我也比较喜欢使用WebForms来开发Web程序.在2008年,微软推出了一

[翻译:ASP.NET MVC 教程]创建路由约束

赶集要发:http://www.ganji18.com 你使用路由约束来使浏览器请求限制在匹配特定路由的中.你可以使用一个正则表达式来具体化一个路由约束. 例如,设想你已在Global.asax文件中定义了清单1中的路由. 清单1--Global.asax.cs routes.MapRoute( "Product", "Product/{productId}", new {controller="Product", action="De

【翻译】ASP.NET MVC 5属性路由

原文链接:http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx#why-attribute-routing 最近在学习MVC相关的东西,今天刚好到msdn上看到了这样的一片文章,感觉不错,于是决定将它翻译出来和博友们一起分享下.我第一次发表文章,有不对的地方非常欢迎指出. —— 写在前面 废话不多说了,咱们开始吧 路由是ASP.NET MVC 怎样去用一个URI去匹配一个

【翻译】MVC Music Store 教程-概述(三)

Controller 与传统的Web框架,将传入的URL通常映射到磁盘上的文件.例如:一个URL请求"/Products.aspx" 或"/Products.php"是处理一个Products.aspx" 或 "Products.php"的文件 MVC框架传入的URL与映射到服务器代码有所不同,而不是将URL传入文件,而是映射到方式方法或者类,这些类被称为"Controller",他们负责处理传入的HTTP请求,处理