MVC 与 webform比较
来自:http://www.cnblogs.com/xiaozhi_5638/p/4019065.html
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中,实现这个是多么复杂。
问题3:HTML并不是服务器返回数据的唯一格式
在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,译者注)。
MVC 与 webform比较的更多相关文章
- Mvc与WebForm优缺点及Mvc的使用
关于Mvc与WebForm的优缺点在网上的评论可谓不胜枚举,但脱离了我们的项目来谈这些意义就不大了.以我们这次改版来看,WebForm的优势有以下几点: 一,可以使用<#include>, ...
- MVC和WebForm 中国省市区三级联动
MVC和WebForm是微软B/S端的两条腿,两种不同的设计理念,相对来说MVC更优于WebForm对于大数据的交互,因为WebForm是同一时间传输所有数据,而MVC它只是传输所用到的数据,更精确, ...
- (读书笔记)Asp.net Mvc 与WebForm 混合开发
根据项目实际需求,有时候会想在项目中实现Asp.net Mvc与Webform 混合开发,比如前台框架用MVC,后台框架用WebForm.其实要是实现也很简单,如下: (1)在MVC 中使用Webfo ...
- ASP.NET MVC与WebForm区别
[转贴一] 使用ASP.NET MVC框架,创建默认项目,第一直观感觉就是地址都是Rewrite过的.对源码和配置文件稍加分析不难看出,MVC使用了httpModules来拦截地址请求,具体用到了Sy ...
- MVC与WebForm的一些区别
MVC与WebForm的一些区别 它们都是ASP.NET WEB开发的两种方式 .但是他们也是有一些不同.做个小结. 1.MVC是没有服务器端控件这么一说的,也就是没有viewstate,也就不会产生 ...
- MVC与WebForm的简单的比较
MVC与WebForm的简单的比较 ASP 强制程序员将业务逻辑和展示页放到一个文件中 WebForm 允许程序员将业务逻辑与页面展示分开到不同的文件中,并且提供强大的开发平台来写 业务逻辑代码 ...
- ASP.NET MVC显示WebForm网页或UserControl控件
ASP.NET MVC显示WebForm网页或UserControl控件 学习与使用ASP.NET MVC这样久,还是对asp.net念念不忘.能否在asp.net mvc去显示aspx或是user ...
- Asp.net Mvc 与WebForm 混合开发
根据项目实际需求,有时候会想在项目中实现Asp.net Mvc与Webform 混合开发,比如前台框架用MVC,后台框架用WebForm.其实要是实现也很简单,如下: (1)在MVC 中使用Web ...
- MVC和WebForm区别
WebForm的理解 1. WebForm概念 ASP.NETWebform提供了一个类似于Winform的事件响应GUI模型(event-drivenGUI),隐藏了HTTP.HTML.JavaSc ...
- .net MVC, webAPI,webForm集成steeltoe+springcloud实现调用服务中心服务的总结
开始之前,如果没接触过Autofac的,可以移步到Autofac官方示例学习一下怎么使用:https://github.com/autofac/Examples .net 下集成steeltoe进行微 ...
随机推荐
- IOS asc码替换
-(void)click:(UIButton *)btn { NSString *testStr = @"学>与全等"; NSStringEncoding encoding2 ...
- 【java开发系列】—— spring简单入门示例
1 JDK安装 2 Struts2简单入门示例 前言 作为入门级的记录帖,没有过多的技术含量,简单的搭建配置框架而已.这次讲到spring,这个应该是SSH中的重量级框架,它主要包含两个内容:控制反转 ...
- java Jsoup 抓取页面数据
List<ImageBean> imgList = new ArrayList<ImageBean>(); ImageBean image = null; String ima ...
- 解决Android Studio 和 Android SDK Manager 无法在线更新的问题.
升级时提示 Connection failed. Please check your network connection and try again 修改安装目录下bin\studio.exe.vm ...
- wf(四)
我们已经在c#和xaml上编写了工作流,或者有的人会觉得在xaml上编写的workflow没什么优点,然而其实xaml其实具有一些很特别的优势. 1. xaml支持工作流设计器,c#不支持: 2. x ...
- error: linker command failed with exit code 1 解决方法之一
出现这种错误的原因可能很多,以下是我遇到的一种情况: 向项目中添加了新文件,没有加入compile source 编译报错: ld: symbol(s) not found for architect ...
- 【20160924】GOCVHelper 图像处理部分(2)
//根据轮廓的面积大小进行选择 vector<VP> selectShapeArea(Mat src,Mat& draw,vector<VP> contour ...
- [Python]实现XMPP协议即时通讯发送消息功能
#-*- coding: utf-8 -*- __author__ = 'tsbc' import xmpp import time #注意帐号信息,必须加@域名格式 from_user = 'che ...
- Python3基础 sort 将一个列表中的值升序排列
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
- Python3基础 isinstance 判断一个变量是否为指定的类型
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...