从三层架构到MVC,MVP

简介:
+关注继续查看
  本来是不想跳出来充大头蒜的,但最近发现园子里关于MVC的文章和讨论之风越刮越烈,其中有些朋友的观点并不是我所欣赏和推荐的,同时最近也在忙着给公司里的同事做MVC方面的“扫盲工作”。所以就搜集了一些大家接触MVC的过程中经常出现的问题做了一下解释说明,希望能与大家多多交流,呵呵。
       当然这种架构模式本身的一些问题也会在接下来的内容就加以介绍,另外就是如果大家有什么不同观点的话,欢迎拍砖(只要不打脸就行,呵呵)。
 
      一.  MVC是谁提出的    
       模型-视图-控制器(MVC)是Xerox PARC在八十年代为编程语言Smalltalk-80发明的一种软件设计模式,至今已被广泛使用。最近几年被推荐为Sun公司J2EE平台的设计模式,并且受到越来越多的使用 ColdFusion 和 PHP 的开发者的欢迎。模型-视图-控制器模式是一个有用的工具箱,它有很多好处,但也有一些缺点。
 
    二.  MVC是否适合进行大项目的开发
      MVC框架肯定是适合于做大项目开发的,但并不是说有了MVC框架我们就可以开发大项目,听起来有些绕,其实道理很简单,原因就是人(开发者)。如果你是一个对MVC框架的设计理念有深入研究的人,那么你在使用MVC框架进行产品和项目开发的时候就会随时随地都要考虑一些问题:
    1.低耦合性(强调视图层和业务层分离)
    2.可测试性(这个非常重要)
    3.高重用性和可适用性
    4.有利于软件工程化管理等等。
      这里我很欣赏老赵的治学态度,因为在他的文章和代码中随时随地都在进行着思考,特别是其对可测试性,单元测试(这里不是什么TDD)的思考,让我看起来有心灵相通的感觉。因为这些问题都是在做中型甚至大型项目中要认真思考的,决不是说微软给的例子就是我们的唯一准则,必定里面有对也有错,我相信在MVC面前,国内甚至微软内部的牛人都不是很多。
       说了这些,大家可以意识到了,如果在没有理解下面这张图以及对MVC的“所谓优点是从何处得到的”有认识,而一上来就去拿MVC去开发大型项目的话,我想不仅不能发挥asp.net MVC框架的估势,相反会时时受制于里面的约束,配置和功能特性,最后感觉还不如直接用asp.net webform开发来的直接,不是吗?真要是到了这一境地,我想不仅无法使用MVC进行大型目开发,就连中小企业应用都应付不来。
         
   
     三.  能不能使用MVC架构进行Webform的开发    
       在园子里有人尝试使用ASP.NET MVC 框架来进行webform方式的开发,我个人是不欣赏这种做法的,这就好比在使用LINQ的项目中又同时使用SQL语句一样“怪异”,这在代码的整体风格上会让人产生迷惑,不是吗?当然老赵也在他的视频课程中提到在webform页面中使用一些MVC功能(比如:ModelBinder等),但我想老赵的本意决不是让这种混合方式的开发大行其道,必定这是“非主流”,所以孰轻孰重还是要大家自己把握的。
   
     四. 传统的三(N)层架构与MVC,以及MVC与MVP关系    
       本文所说的三层架构指:表现层(显示层), 业务逻辑层, 数据访问层(持久化)。如果大家非要“生搬硬套”的把它与MVC扯上关系的话,那我就只能在这里"强扭这个瓜"了,即:
     三层架构中"表现层"的aspx页面对应MVC中的View(继承的类不一样)    
     三层架构中"表现层"的aspx.cs页面(类)对应MVC中的Controller,理解这一点并不难,大家想一想我们以前写过的Redirect,当然它本身就是跳转了一些链接页面,而MVC中的Controller要做的更爽,它控制并显示输出了一个视图。即然所起到的作用都是对业务流程和显示信息的控制,只不过是实现手段不同而已。
      三层架构中业务逻辑层和数据访问层对应MVC中的Model(必定View和Controller已找到“婆家”,剩下的Model只能是业务业务层和数据访问层的了,呵呵)。但其实微软的一些MVC示例项目中对这个问题理解的并不是这样简单,这一点在我之前的关于两个MVC示例的思考(MVCStore和Oxite) 已阐述过,就不多说了。  
    
     其实明白了这个关系,就可以尝试把以前的三层结构迁移到MVC框架下,当然在这个过程中肯定会遇到这样或那样的问题,但原则就是把将MVC的优势发挥到极致,要不然还不如不做。
     说到这里,其实早在N年前就有人提出使用FrontController(前端控制器)来实现对HTTP页面请求的路由跳转(包括数据的展现),说白了就是使用HttpHandler来进行页面请求的处理和数据绑定,而不是完全“指望”普通的页面访问重定向等。这样做的目的,就我而言与Routing中的Controller和Action的出发点标是一致的,只不过Routing实现的更优雅同时也更底层一些。
     说完了三层架构,再看看MVC与MVP,其实在这之前我们有必要看一下这张图:
 
         
     看完了上面的图,大家就会发现MVP与MVC最大的一个区别就是“Model与View层之间倒底该不该通信(甚至双向通信,如图)。我想这也是目前做这两方面研究的专家所互相争论的战场。必定各有各的好处和因好处要付出的代价。起码在MVP模式下的Presenter要拥有“绝对权力”。如果没有它,MODEL与View就是两个孤岛,尽管各有各的地盘(完全解耦),但不会给企业带来什么有用的价值。
所以我这里有一个比喻来形容MVP中的:
     Presenter ----就是一个控制欲极强的女人,甚至就连“用什么姿势”,它都要管一管。
    
     当然日里万机操心多了就会让自己要做的事越来越多,最终它面临的就是该层代码日益庞杂,且书写起来不太方便,必定就连事件绑定这类鸡毛算皮的事都要归它管,累不累呀。最终我们看到MVP中的View就真的代码轻闲了不少(国企职工嘛),难怪说View只要从相应的IVIEW接口下实现相应的属性和一些简单方法就完事了,而最终调用IVIEW接口下的那个视图实例则完全交给了Presenter,
这让我想到了MVC中可以支持“自定义模版引擎(最终由MVC框架来控制使用系统还是自定义的模版引擎)”以及平时大家常挂在嘴边的换肤功能,想到这里多少还真有那么点意思了(精神层面上)。
     当然在微软内部对MVP的理解也有所不同,如下图中所说的Supervising Controller模式和上面大家看到的PassiveView.
 
     Supervising Controller模式其实很接近于MVC的那张图了,只是又提供了Presenter与View之间的“双向通信”。这种做法也是有很多不同意见的,起码对那些支持“单向依赖”的开发者而言是“嗤之以鼻”的。
     说到这里,表达一下我的观点,我是偏向于PassiveView的,虽然这种模式有些霸道,但必定是让Model和View之间真正解耦,为开发者提供了最大的“控制成就感”,可以说想怎么控制视图就怎么控制,但因此所造成的问题就是代码书写量和实现复杂性等问题了。
      
     五.  Controller和Model中该有哪些东东    
     因为VIEW中的逻辑比较简单,所以对系统复杂性的考虑基本上要重点放在Model中,而Controller是对业务流程的控制,其应该保持“代码清爽”。说是这么说,但实际进行项目开发时这两者之间的界线能这么清楚吗,答案是“尽量保(坚)持”。必定这是MVC的“特色”嘛。
     另外这里向大家推荐一个不错的方法"Robustness",有了它您就可以很容易的找出那些系统方法要放在MODEL中,哪些该归入控制逻辑中了,该方法我在两年前的一篇文章中提到过,大家感兴趣的话可以看看这个链接, 采用[ICONIX] 方法实践BLOG设计之四 [健壮性分析] .
     
其核心内容如下:   
     实体对象(entity object):
         通常是来自域模型中的对象(也就是现实世界),它常对应于数据库表和文件,这些数据表   和文件中存储了执行用例所需的数据。有些实体对象是“临时”对象(如搜索结果),当用例   结束后将消失。

   边界对象(boundary object):
         参与者使用它来同系统交互,这通常包含窗口,屏幕,对话框和菜单。如果有GUI原型,   将会知道许多主要的边界对象是什么。

   控制对象(control object):
         将边界对象和实体对象关联起来(通常被称为控制器,因为它们通常不是真正的对象),   它包含了大部分应用逻辑,它们在用户和存储的数据之间架起一座桥梁。控制对象中包含经常   修改的业务规则和策略。这样修改只需要在这些对象中进行,而不会涉及到用户界面和数据库   模式。控制器偶尔 (20%的时间内)也会是设计中的“真正对象”,但大部分时间内,控制器只是一个占位符,用于避免您遗漏用例要求的任何功能和系统行为。
  
      上面的三个对象分别对应Model, View, Controller.
     
      正如文中所说,该方法还提供了如下好处:    
   1.它帮助您确保用例文本的正确性,且没有指定不合理或不可能的行为 (基于要使用的一组对 象),从而提供了健康性检查。
   2.帮助确保用例考虑了所有必需的分支流程,从而提供了完整性和正确性检查。
   3.让您能够(持续)发现对象,因为在域建模期间可能会遗漏一些对象, 而这些对象在绘制时序图时不易被发现,并且很可能正是它导致无法绘制时序图。
   4.缩小分析和设计的鸿沟,从而最终完成初步设计(关于初步设计复核会在下一篇中介绍)。
 
      六.MVC与MVP是否可以同时出现在一个SLN甚至一个项目中   
      这一点我想谁说了都不算数,只有用户需求才是王道,用户使用在当前项目中实现某些特定功能,而该功能恰恰是MVC或MVP的用武之地,那就一个字:“”。

      最后还要再说明一点:
   
      
业务逻辑是系统架构中体现核心价值的部分。它的关注点主要集中在业务规则的制定、业务流程的实现等与业务需求有关的系统设计,所以说一个系统来说,业务逻辑是无处不在的。View上的是显示逻辑,Controller上是流程控制逻辑),Model上简直就是“逻辑大本营”了。     
      使用 MVC 框架时我们要将“经常变化”的业务规则(位于Controller)和相对稳定的业务逻辑(位于Model)分离开,同时在Model层采用接口方式实现,以此来应对将来不断变化的业务需求。
      好了,今天的内容就先到这里了。


本文转自 daizhenjun 51CTO博客,原文链接:http://blog.51cto.com/daizhj/154456,如需转载请自行联系原作者
相关文章
|
4月前
|
前端开发 JavaScript UED
|
5月前
|
存储 缓存 前端开发
|
11月前
|
前端开发 Java 程序员
iOS开发 - 抛开表面看本质之iOS常用架构(MVC,MVP,MVVM)
iOS开发 - 抛开表面看本质之iOS常用架构(MVC,MVP,MVVM)
290 0
|
11月前
|
设计模式 前端开发 JavaScript
浅谈MVC、MVP、MVVM框架模式
浅谈MVC、MVP、MVVM框架模式
|
XML 存储 设计模式
Jetpack 系列(5)—— Android UI 架构演进:从 MVC 到 MVP、MVVM、MVI
Jetpack 系列(5)—— Android UI 架构演进:从 MVC 到 MVP、MVVM、MVI
294 0
Jetpack 系列(5)—— Android UI 架构演进:从 MVC 到 MVP、MVVM、MVI
|
设计模式 XML 存储
Android实战 | 详解MVC、MVP模式并分别实现登录界面案例
Android实战 | 详解MVC、MVP模式并分别实现登录界面案例
|
设计模式 XML 存储
vue相关面试题:MVC,MVP,MVVP三种设计模式的区别
patch 阶段根据 VNode 创建真实节点树,核心方法为 createElm,首先遇到组件类型的 VNode,内部会执行 $mount,再走一遍相同的流程。普通节点类型则创建一个真实节点,如果它有子节点开始递归调用 createElm,使用 insert 插入子节点,直到没有子节点就填充内容节点。最后递归完成后,同样也是使用 insert 将整个节点树插入到页面中,再将旧的根节点移除。
135 0
|
XML 前端开发 JavaScript
【Android】MVC,MVP,MVVM的优缺点
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构.
219 0
【Android】MVC,MVP,MVVM的优缺点
|
XML 存储 前端开发
Android的MVC MVP MVVM模式
学习Android的同学一定要了解的三种开发模式,不然自己写的项目采用的什么模式都不清楚
123 0
|
XML 前端开发 数据处理
Android——MVC、MVP、MVVM框架实现登录示例
MVC 描述 缺点 优点 MVP 效果图 描述 缺点 优点 代码解析 视图效果图 建立实体类 建立实体类接口 实现实体类接口 设置P层 建立交互接口 数据绑定 MVVM 效果图 描述 代码解析 导入dataBinding 实体类 建立viewmodel xml绑定数据 视图与数据绑定
325 0
Android——MVC、MVP、MVVM框架实现登录示例
相关产品
云迁移中心
推荐文章
更多