ASP.NET MVC 5
第1章 ASPNET+MVC ASPNET MVC是一个全新的Web应用框架烀术语 ASPNET MVO拆分开 来,即 ASPNET+MVC。前者代表支撑该应用框架的技术平台,它表明 ASPNET MVC和传统的 Web forms应用框架一样,都是建立在 ASPNET平台之上;后 者则表示该框架背后的设计思想意味着 ASPNET MVC采用了MVC架构模式。 ASPNETMVC5框架起秘 2口第1章 ASPNET+MVC 1.1传统MVC模式 对于大部分面向最终用户的应用来说,它们都需要只有一个与用户进行交互的可视化UI 界面,我们将这个U称为视图(iew)。在早期,我们倾向于籽所有与UI相关的操作糅合在 一起,这些操作包括UII界面的呈现、用户交互操仵的捕捉与响应、业务流程的执行及对数据 的存取等,我们将这种设计模式称为自治视图( Autonomous view,AV)。 1.1.1自治视图 说到白治视图,很多人会感到陌生,但是我们(尤其是NET开发人员)可能经常采用这 种模式来设计我们的应用。 Windows forms和 ASPNET Web forms虽然分别属于GU1和Web 应用开发框架,但是它们都采用了事件驱动的开发方式,所有与UI相关的逻辑都可以定义在 针对视图( Windows forn或者 Web forn)的后台代码( Code behind)中,并最终注册到视图 本身或者视图元素(控件)的相应事件上。 个典型的人机交互应用具有3个主要的关注点,即数据在可视化界面上的呈现、UI处理 逻辑〔用于处理用户交互式操作的逻辑)和业务逻辑。自治视图模式将三者混合在一起,势必 会带来如下一些问题。 ●重用性。业务逻辑是与UI无关的,应该最大限度地被重用,但是若将业务逻辑定义在自 治视图中,相当于使它完全与视图本身绑定在一起。除此之外,如果我们能够将UI的行 为抽象出来,基于抽象化UI的处理逻辑也是可以被共享的,但是定义在自治视图中的UI 处理逻缉也完仝丧失了重用的可能。 ·稳定性。业务逻辑具有最强的稳定性,UI处理逻辑次之,可视化界面上的呈坝最差(比如 我们经常会为了更好地呈现效果来调整HTML)。如果将具有不同稳定性的元素混合为一体, 那么具有最差稳定性的元素决定了整体的稳定性,这是“短板理论”在软件设计中的体现 可测试性。仟何涉及UI的组件都不易测试,因为U是旱现给人看的,并且会与人进行交 互,用机器来模拟活生生的人对组件实施自动化测试本就不是一件容易的事。 为了解决自治视图导致的这些问题,我们需要采用关注点分离( Seperation of Concerns, SoC)的原则将可视化界面呈现、UI处理逻辑和业务逻辑三者分离出来,并且采用合理的交互 方式将亡们之间的依赖降到最低。将三者“分而治之”,自然也使UI逻辑和业务逻辑变得更容 易测试,测试驱动设计与开发也得以实现。这里用于进行关注点分离的模式就是MC AS尸 NETMVC5框架秘 1.1.2什么是MVC模式 MC的创建者是 Trygve M.H. Rccnskau,他是挪威的计算机专家,同时也是奧斯陆大学的名誉 教授。MVC是他在1979年访问施乐帕克研究中心( Xerox Palo allo research center, XeRox PARo) 期间提出的一科主要针对GU应用的软件架构模式。 Trygve最初对MC的描述记录在4 pplications Programming in Smalitalk-80IM: How to use model-View-Controller(MC这篇论文中,有兴趣的读者 可以通过地址htp:/ist-www.csillinois.cduuscrs/smarch/st-docs/myc.html阅读这篇论文。 MVC休助∫“关注点分离”这一基木的设计方针,它将一个人机交互应用涉及的功能分 为 Model、 Controller和view三部分,它们各自具有如下的职责。 · Model是对应用状态和业务功能的封装,我们可以将它理解为同时包含数据和行为的领域 模型( Domain model)。 Modcl接受 Controller的请求并完成相应的业务处理,在应用状态 改变的时候可以向View发出相应的通知。 View实现可视化昇面的呈现并捕捉最终用户的交互操作(如鼠标和键盘操作)。 ·View捎获到用户交互操作后会直接转发给 Controller,后者完成相应的U逻辑。如果需要 涉及业务功能的调用, Controller会直接调用Modl在冗成U处理之后, Controller会根 据需要控制原View或者创建新的vew对用户交互操作予以响应 图1-1揭示了MVC模式下 Model、View和 Controller之间的交互。对于传统的MVC模式 来说,很多人会认为 Controller仅仅是View和 Model之间的中介。实则不然,Vew和 Model 之间存在直接的联系,View不仅可以直接调用Mode查询其状态信息,当 Model的状态发生 改变的时侯,它也可以直接通知View比如在一个提供股票实时价位的应用中,维护股价信息 的 Model在股价变化的情况下可以直接通知相关的vew改变其显示信息。 State Notification Model D State Query User Actions View Controller View Selection 图1-1Mode- View-Controller之间的交互 ASPNETMVC5框架起秘 4第1章 ASPNET+MVC 从消息交换模式的角度来讲,不论是 Model在应用状态发生改变时通知View,还是view 在捕捉到用户的交互操作后通知 Controller,消息都是以“单向(One-Way)”方式流动的,所 以我们推荐釆用事件机制来实现这两种类型的通知。从设计楨式的角度来讲就是采用观察者 ( Observer)模式通过注册/订阅的方式米实现它们,具体来讲就是让vew作为Mode的观察 名通过注册相应的事件来检测状态的改变,让 Controller作为View的观察者通过注册相应的事 什来处理用户的交互操作。 我们看到很多人将MVC和所请的“三层架构”进行比较,其实两者并没有什么可比性 MVC更不是分别对应着UI、业务逻辑和数据取3个层次,不过两者也不能说完全没有关系。 Trygve M.H.Rε ensky提出MvC的时候是将其作为构建整个GUI应用的架构模式,这种情况 下的 Model实际上维护着整个应用的状态并实现了所有的业务逻辑,所以它更多地体现为一个 领域模型。 对于多层架构来说(比如我们经常提及的三层架构),MVC是被当成UI呈现层( Presentation Laver)的设计模式,而 Model则更多地体现为访问业务层的入口( Gateway)。如果采用面向 服务的设计,业务功能被定义成相应服务并通过接∏(契约)的形式暴露出来,这里的 Model 还可以表示成进行服务调用的代理。 1.2MVC的变体 我们可以采用MVC模式将可视化UI元素的呈现、UI处理逻辑和业务逻辑分别定义在 View、 Controller和 Model中,但是MVC并没有对三者之间的交互进行严格的限制。这主要体 现在它允许View和 Model绕开 Controller进行直接交互,不仅View可以通过调用 Model获取 需要旱现给用户的数据, Model也可以直接通知Viw计其感知到应用状态的变化。当我们将 MVC应用于只体的项目开发时,不论是基于GUI的桌面应用还是基于浏览器的Web应用,如 果不对Modl、VView和 Controller之间的交互作更为严格的约束,我们编写的稈序可能比自治 视图更加难以维护 今天我们将MVC视为一种模式( Pattern),但是作为MvC最初提出者的 Trygve M.H Reenskau却将MVC视为一种范例( Paradigm),这可以从他在 Applications Programming in Snlk8 0(TM): How to use Model-View-Controller(MVC/中对MVC的描述可以看出来: In the MvC Paradigm the user input, the modeling of the external world, and the visual feedback to the user are explicitly separated and handled by three types ofobject, each specialized for its tusk 模式和范例的区别在于前者可以直接应用到具体的应用上,而后者则仅仅提供一些基本的 AS尸 NETMVC5框架秘 指导方针。在我看来,MVC是一个很宽泛的概念,任何基于 Model、View和 Controller对Ul 应用进行分解的设计都可以称为MVC。当我们采用VIVC的思想来设计U应用的时候,应该 根据开发框架(比如 Windows forms、WPF和 Web forms)的特点对 Model、View和 Controller 设置一个明确的界限,同时为它们之间的交互制定一个更为严格的规则。 在软件设计的发展历程中出现了一些MVC的变体( Variation),它们遵循定义在MVC中 的基本原则,但对于三元素之间的交互制定了更为严格的规范。我们现在就来简单地讨论几种 常用的MVC变体。 1.2.1MVP MVP是一种广泛使用的UI架构模式,适用于基于事件驱动的应用框架,比如 ASPNET Web Forms和 Windows forms应用。MVP中的M和V分别对应于MVC的Mode和View,而P ( Presenter)则自然代替了MVC中的 Controller。但是MvP并非仅仅体现在从 Controller到 Presenter的转换,而是更多地体现在 Model、View和 Presenter之间的交互上。 MVC模式中三元素之间“混乱”的交互主要体现在允许View和 Model绕开 Controller进 行单独“交流”,这个问题在MVP模式中得到了彻底解决。如图1-2所示,能够与 Model直接 诖行交互的仅限于 Presenter,iew只能道过 Presenter间接地凋用 Model。 Model的独立性在这 里得到了真正的体现,它不仅仅与可视化元素的呈现(View)无关,与UI处理逻辑( Presenter) 也无关。使用MVP的应用是用户驱动的而非 Model驱动的,所以 Model不需要主动通知View 以提醒状态发生了改变。 Vi lew Presenter IView Model 图1-2Mode-VeW- Presenter之间的交互 MVP不仅仅避免了View和 Model之间的深度耦合,更进一步地降低了 Presenter对View 的依赖。如图1-2所示, Presenter依赖的是一个抽象化的iew,即具体View实现的接口 IView 这带来的最直接的好处就是使定义在 Presenter中的UI处理逻辑变得易于测试。由于Prε senter ASPNETMVC5框架起秘 6第1章 ASPNET+MVC 对View的依赖行为定义在接口 IView中,我们只需要VIock一个实现了该接口的View就能对 Presenter进行测试 构成MVP三要素之间的交互体现在两个方面,即View与 Presenter及 Presenter与 Mode 之间的交互。 Presenter和 Model之间的交互很清晰,它仅仅体现为 Presenter对Mode的单向 调用。View和 Presenter之间该采用怎样的交互方式是整个MVP的核心,MVP针对关注点分 离的初衷能否体现在具体的应用中,很大程度上取决于两者之间的交互方式是否正确。按照 View和 Presenter之间的交互方式,以及View本身的职责范围, Martin folwer将MVP分为PV ( Passive view)和sC( Supervising controller)两种模式。 1.PV与SC 解决viiew难以测试的最好办法就是让它无须测试。如果viiew不需要测试,其先决条件就 是让它尽可能不涉及UI处理逻辑,这就是PV模式的目的所在。顾名思义,PV( PassiveView) 是一个被动的iew,定义其中的针对UI元素(比如控件)的操作不是由View自身主动来控 制,而是被动地交给 Presenter来操控。 如果我们纯粹地采用Pv模式来设计View,意味着我们需要将viiew中的UI元素通过属性 的形式暴露出来。具休来说,当我们在为View定义接口的肘傧,需要定义基于U元素的属性 使 Presenter可以对vicw进行细粒度操作,但这并不意味着我们直接将Vicw上的控件暴露出 来。举个简单的例子,假设我们开发的HR系统中只有如图1-3所小的一个Web页面,我们通 过它可以获取某个部门的员工列表。 幽员工管理 cDlocalhost36500 查询 姓名 性别 销售部 张三 采购部1 销售部 人事部 李四 男 21/09/1981 图1-3员工查询页面 假设现在通过 ASPNET Web forms应用来设计这个页面,我们米讨论一下如果采用IV模 式View的接口该如何定义。对于 Presenter来说,iew供它操作的控件有两个,一个是包含所 AS尸 NETMVC5框架秘 有部门列表的 DropDownList,另一个则是显小员工列表的 Grid view。在页面加载的时候, Presenter将部门列表绑定在 DropDOwnlist上,与此同时包含所有员工的列表被绑定到( gridview 上ε当用户选择某个部门并单击“查询”按钮后,view将包含筛选部门在内的查询请求转发给 Presenter,后者筛选出相应的员⊥列表之后将其绑定到GridView 如果为该viiew定义一个接口 EMployee view,我们不能按照如下所示的代码将上述这两个 控件直接以属性的形式暴露出来。针对具体控件类型的数据绑定属于viiew的内部细节(比如 说针对部门列表的显示,可以选择 DropDownlist,也可以选择 ListBox),不能体现在表示用于 抽象View的接口中。除此之外,理想情况卜定义在 Presenter中的U处理逻辑应该是与具体的 技术平台无关的,如果在痿口屮涉及控件类型,这无疑将 Presenter与具体的技术平台绑定在了 public interface IEmp-oyeeview D DeparLmmenls geLi 1 Gridview Employees i geti I 正确的接口和实现该接口的View(一个Web页面)应该采用如卜的定义方式: Presenter 通过对属性 Departments和 Employee赋值来实现对相应 Drop downList和 Grid view的数据绑 定,冋时通过属性 Selectedε partment得到用户选择的筛选部门。为∫尽可能让接冂只暴露必 需的信息,我们还特意将对属性的读/写作了控制。 public inTerlace IEmpLoyeeVie IEnumerable Departmmer-s Seleted IEnumerable Employees I seti 1 public partial class employeeview: Page, IEmployeev-ew //其他成员 pu上1⊥ C TEnT.Ime this. DropDownListDepartments, DataSource valuei this Drop DownListDepartments DataBind( public string SelectedDepartment ge=t return this. DropDownListDepartments. Selectedvalue; j ASPNETMVC5框架起秘 8第1章 ASPNET+MVC public IEnumerable Employees this GridviewEmployees DataSource value this. GridviewEmployees DataBind()i PV模式将所有的UI处理逻辑全部定义在 Presenter上,意味着所有的U处理逻辑都冋以 被测试,从可测试性的角度来看这是一种不错的选择。但是它要求将Vcw中可供操作的UI元 素定义在对应的接口中,对于一些复杂的富客户端( Rich client)应用的View来说,接口成员 的数量将可能会变得很多,这无疑会提升编程所需的代码量。从另一方面来看,由于 Presenter 需要在控件级别对viiew进行细粒度的控制,这无疑会提高Prε senter本身的复杂度,往往会使 原本简咩的逻輯复杂化。在这种情况下我们往往采用SC模式 在SC模式下,为了降低 Presenter的复杂度,我们倾向于将诸如数据绑定和显示数据格式 化这样简单的UI处珵逻辑转移到viiew中,这些处理逻辑会体现在VIiew实现的接口中。尽管 Viw从 Presenter中接管」部分UI处理逻辑,但是 Presenter依然是整个三角关系的驱动者, View被动的地位依然没有改变。对于用户作用在Vew上的交互操作,View本身并不进行响应, 它只会将交互请求转发给 Presenter,后者在独立完成相应的处理流程(可能涉及针对 Model的 调用)之后会驱动View对用户交互请求进行响应 2.eW和 Presenter交互的规则(针对SC模式) viiew和 Presenter之间的交互是整个MvP的核心,能否正确地应用MVP模式来架枃我们 的应用,主要取决于能否正确地处理View和 Presenter两者之间的关系。在由 Model、View和 Presenter组成的一角关系中,核心元素不是Vew而是 Presenter, Presenter不是View调用 Model 的中介,而是最终决定如何响应用户交互行为的决策者。 View可以理解为 Presenter委派到前端的客户代理,而作为客户的自然就是最终的用户。 对于体现为鼠标/键盘操作的交互请求应该如何处理,作为代理的viiew并没有决簧权,所以它 只能将请求汇报给委托人 Presenter eView向 Presenter发送用户交互请求应该采用这样的口吻: “我现在将用户交互请求发送给你,你看着办,需要我的时候我会协助你”,而不应该是这样 “我现在处理用户交互请求」,我知道该怎么办,但是我需要你的支持,因为实现业务逻辑的 Modc只信仟你” AS尸 NETMVC5框架秘
用户评论