MVC, MVP, MVVM比较以及区别

MVC, MVP和MVVM都是用来解决界面呈现和逻辑代码分离而出现的模式。之前只是对它们有部分的了解,没有深刻的研究过,对于一些里面的概念和区别也是只知其一;不知其二。如今一边查资料,并结合本身的理解,来谈一下对于这三种模式思想的理解,以及它们的区别。欢迎各位高手拍砖。php

阅读目录:html

一. MVC, MVP, MVVM诞生的需求?java

二. 一段典型的耦合代码web

三. MVC模式后端

     3.1 主动MVC服务器

     3.2 被动MVC架构

     3.3 Web应用中的MVC框架mvc

     3.4 MVC总结app

一,MVC, MVP, MVVM诞生的需求?

软件中最核心的,最基本的东西是什么? 是的,是数据。咱们写的全部代码,都是围绕数据的。 围绕着数据的产生、修改等变化,出现了业务逻辑。 围绕着数据的显示,出现了不一样的界面技术。 框架

没有很好设计的代码,经常就会出现数据层(持久层)和业务逻辑层还有界面代码耦合的状况。

ORM等框架,解耦合了业务逻辑和数据之间的耦合,业务逻辑再也不关心底层数据如何存储和读取。全部数据呈现给业务逻辑层的就是一个个的对象。 而MVC, MVP, MMVM用来解决业务逻辑和视图之间的耦合。

二,一段典型的耦合代码

复制代码
{

SqlDataAdapter adapter = new SqlDataAdapter("select * from Table1","server=.;database=db;uid=sa;pwd=password"); DataSet ds = new DataSet("ds1"); adapter.Fill(ds); this.GridView1.DataSource = ds; this.GridView1.DataBind(); }
复制代码

上面的这段代码中,既包含了数据访问,还包含的页面展现。当项目复杂程度更高,这种代码就会变得很是难以维护,层次也不清晰。

三,MVC模式

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可使用不一样的表现形式

3.1 主动MVC

MVC的理论思想对应的是主动MVC, 这里的主动的意思是, Model会主动通知View更新。而咱们使用MVC框架, Struts, asp.net mvc等都不是主动MVC(视图的更新都是经过Controller完成的)

Model

用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。 模型中数据的变化通常会经过一种刷新机制被公布。为了实现这种机制,那些用于监视此模型的视图必须事先在此模型上注册,从而,视图能够了解在数据模型上发生的改变。

View

视图层负责数据的展现。 在视图中通常没有程序上的逻辑。为了实现视图上的刷新功能,视图须要访问它监视的数据模型(Model),所以应该事先在被它监视的数据那里订阅Model的事件。

Controller

控制器是M和V之间的链接器,用于控制应用程序的流程。它处理事件并做出响应。“事件”包括用户的行为和数据模型上的改变。

 

image

 

3.2 被动MVC

下图是被动MVC中的流程,和主动MVC不一样之处是, View没有订阅Model数据变化的事件,等待Model来通知须要根据新的数据来更新View. 在被动MVC中,Controller负责通知View, 有数据变化,须要更新视图。

image

 

被动MVC 中,与主动MVC的区别在于: 一、模型对视图和控制器一无所知,它仅仅是被它们使用     二、控制器使用视图,并通知它更新数据显示     三、视图仅仅是在控制器通知它去模型取数据的时候它才这么作(视图并不会订阅或监视模型的更新) 

3.3. Web应用中的MVC框架

Web中的MVC框架都是被动MVC模式,由于web应用中, 因为http是基于请求和响应方式协同工做的,所以当服务器端的model(数据)发生变化时,它不会当即更新客户端的view,只有客户端从新请求或刷新页面时才更新.

下图是典型的MVC框架中的MVC一个请求流程。

image

3.4 MVC总结

MVC优势

  • 因为MVC很好的分离了视图层和业务层,因此它具备如下优势
  • 耦合性低
  • 开发速度快
  • 可维护性高
  • 没有控件的概念,对html没有封装,易于理解
  • 和其它平台(java, php)等更加类似。便于人才获取

 

MVC使用的误区

1.把Model理解成实体类(Entity),在MVC中Model应该包含2部分功能,一部分是处理业务逻辑,一部分是提供View显示的数据 2.把业务逻辑所有放在Controller端

这两个误区本质上都是对Model的做用不明致使的。

Model在MVC架构中起的做用很是重要,它应该是业务逻辑真正的实现层。因此Model的其实是Business Model(业务模型)。而Controller仅仅起一个“桥梁”做用,它负责把View的请求转发给Model,再负责把Model处理结束的消息通知View。Controller是用来解耦View和Model的,具体一点说,就是为了让UI与逻辑分离(界面与代码分离)。

引自http://www.techopedia.com/definition/27454/model-mvc-aspnet

Techopedia explains Model (MVC)

The Model is the part of MVC which implements the domain logic. In simple terms, this logic is used to handle the data passed between the database and the user interface (UI).

The Model is known as domain object or domain entity.      The domain objects are stored under the Models folder in ASP.NET. The domain model represents the application perspective for the data to be handled whereas a view model is required to produce the engine that generates the View.

This definition was written in the context of ASP.NET.

 

MVC的缺点

完美的MVC应用场景应该是这样的:

有个Student Model, 关联StudentListView,  StudentEditView. 对于StudentListView, Student Model提供Student的集合数据来显示StudentListView 对于StudentEditView, Student Model提供单个Student数据来展现StudentEditView而且响应StudentEditView的保存操做。

可是这只是完美的状况,实际应用中,在ListView上,不仅仅显示Student的信息,可能还须要这个Student的历史成绩,家庭状况,  老师信息。而这些是Student Model不能提供的。 也许咱们能够扩展Student Model, 将Student Model可以提供的信息扩展,包含成绩信息等,这自己也能够。可是,若是Student显示的View,这个须要只是须要额外的成绩信息,另外一个View只是须要额外的家庭信息,Student Model是否是有些疲于奔命,你能知道还会有多少个差别化的View的需求? 并且让逻辑端代码这样不断的修改来适应View端,好吗?

因为MVC的设计思想是从Model出发,而没有考虑到View端的复杂性,这样致使的问题是Model难以符合复杂多变的View端变化。 相对这点,MVP和MVVM就要好得多。它们都独立出了Presenter 和ViewModel来对应每一个View。

 

 

四. MVP模式

 

     4.1 MVP的思想

     4.2 UI界面接口化

     4.3 Presenter —— Model和View之间的桥梁

     4.4 MVP的代码结构和时序图

     4.5 MVP模式总结

 

五. MVVM模式

     5.1 MVVM模式的设计思想

     5.2 MVVM模式结构图

 

六. MVC, MVP和MVVM模式使用场景总结

 

四, MVP模式

 

MVP模式也是一种经典的界面模式。MVP中的M表明Model, V是View, P是Presenter。 下面例子中的完整代码,能够在这里下载:  WinformMVP源码 你们还能够比较园中Artech的这篇文章 谈谈关于MVP模式中V-P交互问题

 

4.1 MVP的思想

 

MVP模式在我看来,是一个真正意义上的隔离View的细节和复杂性的模式。为何这么说: 由于在其它模式中V都表明的是UI界面, 是一个html页面,XAML文件或者winform界面。可是在MVP模式中的V表明的是一个接口,一个将UI界面提炼而抽象出来的接口。接口意味着任何实现了该接口的界面,都可以复用已有的Presenter和Model代码。

 

4.2 UI界面接口化

 

要很好的理解MVP, 就要有把UI界面接口化的能力。看下面的界面中,将红色标记的User Control抽象一下,就能获得下面的接口

 

image

 

复制代码
public interface IUserAdd { event EventHandler UserAddEvent; string UserName { get; set; } string UserAge { get; set; } }
复制代码

 

界面中的2个输入框被抽象成了UserName和UserAge两个属性。Save按钮的点击事件,被抽象成了事件UserAddEvent。winform中实现该接口的代码以下:

 

复制代码
public partial class UserAdd : UserControl, IUserAdd { public event EventHandler UserAddEvent; public string UserName { set { this.txbName.Text = value; } get { return this.txbName.Text; } } public string UserAge { set { this.txbAge.Text = value; } get { return this.txbAge.Text; } } public UserAdd() { InitializeComponent(); } private void btnAdd_Click(object sender, EventArgs e) { if (UserAddEvent != null) UserAddEvent(this, e); } }
复制代码

 

下面拿UserAge属性来解释一下,UI界面接口化的魔力。当后端代码要获取界面上的年龄值,就只须要get属性, 要更新界面显示的时候,就只须要set属性。 这个时候,后端代码对于界面的操做,被抽象成了对于UserAge属性的操做了,也就是和具体的界面显示无关了。

 

4.3 Presenter —— Model和View之间的桥梁

 

上文提到的后端代码中,包含了P和M. M和MVC中同样,指的是逻辑代码。P则是Model和View之间的桥梁,负责将对应的Model和View组合到一块儿。

 

针对上面的IUserAdd, 对应的Presenter代码是:

 

复制代码
public class UserAddPresenter:IPresenter { private readonly IUser _model; private readonly IUserAdd _view; private readonly ApplicationFacade _facade = ApplicationFacade.Instance; //这里的facade是Presenter之间通讯用的,详细能够看完整代码 //Presenter构造函数中,将view和model做为参数传入 public UserAddPresenter(IUser model, IUserAdd view) { _model = model; _view = view; WireUpViewEvents(); } private void WireUpViewEvents() { _view.UserAddEvent += _view_UserAdd; } //当view的UserAdd事件触发,取得UI中的数据,调用model逻辑处理,添加新用户。 //同时发送User_ADDED消息到系统中(系统中其它UI部分接收消息,好比这里的DataGrid,它接收到User_ADDED以后,会刷新) private void _view_UserAdd(object sender, EventArgs e) { var user = new User { Name = _view.UserName, Age = Convert.ToInt32(_view.UserAge) }; _model.AddItem(user); _facade.SendNotification(ApplicationFacade.USER_ADDED); } }
复制代码

 

4.4 MVP的代码结构和时序图

 

这里的MVP中的代码结构图和时序图,可以更好的帮助理解MVP模式

 

MVP-Structure

 

 

 

Picture2 

 

4.5 MVP模式总结

 

在MVP里,Presenter彻底把Model和View进行了分离,主要的程序逻辑在Presenter里实现。并且,Presenter与具体的 View是没有直接关联的,而是经过定义好的接口进行交互,从而使得在变动View时候能够保持Presenter的不变,即重用! 不只如此,咱们还能够编写测试用的View,模拟用户的各类操做,从而实现对Presenter的测试 —— 而不须要使用自动化的测试工具。 咱们甚至能够在Model和View都没有完成时候,就能够经过编写Mock Object(即实现了Model和View的接口,但没有具体的内容的)来测试Presenter的逻辑。

 

MVP的优点

 

一、模型与视图彻底分离,咱们能够修改视图而不影响模型 二、能够更高效地使用模型,由于全部的交互都发生在一个地方——Presenter内部     三、咱们能够将一个Presener用于多个视图,而不须要改变Presenter的逻辑。这个特性很是的有用,由于视图的变化老是比模型的变化频繁。     四、若是咱们把逻辑放在Presenter中,那么咱们就能够脱离用户界面来测试这些逻辑(单元测试)

 

五, MVVM模式

 

5.1 MVVM模式的设计思想

 

MVVM模式中,一个ViewModel和一个View匹配,它没有MVP中的IView接口,而是彻底的和View绑定,全部View中的修改变化,都会自动更新到ViewModel中,同时ViewModel的任何变化也会自动同步到View上显示。

 

这种自动同步之因此可以的缘由是ViewModel中的属性都实现了observable这样的接口,也就是说当使用属性的set的方法,都会同时触发属性修改的事件,使绑定的UI自动刷新。(在WPF中,这个observable接口是 INotifyPropertyChanged; 在knockoutjs中,是经过函数ko.observable() 和ko.observrableCollection()来实现的)

 

因此MVVM比MVP更升级一步,在MVP中,V是接口IView, 解决对于界面UI的耦合; 而MVVM干脆直接使用ViewModel和UI无缝结合, ViewModel直接就能表明UI. 可是MVVM作到这点是要依赖具体的平台和技术实现的,好比WPF和knockoutjs, 这也就是为何ViewModel不须要实现接口的缘由,由于对于具体平台和技术的依赖,本质上使用MVVM模式就是不能替换UI的使用平台的.

 

5.2 MVVM模式结构图

 

这里是MVVM模式的结构图,可以帮助更加容易的理解MVVM模式:

 

blog-mvvm

 

 

 

六, MVC, MVP和MVVM模式使用场景总结

 

因为在winform中没法像WPF同样,支持数据和界面的双向绑定以及事件的监控,因此,在winform中MVP是最佳选择。 WPF和html界面中使用Knockout,实现了observable, 因此使用MVVM.(应该说WPF就是为使用MVVM设计的) 在web应用中,因为http是基于请求和响应方式协同工做的, 没法一直保持链接状态,因此没法达到MVP中Presenter之间的消息传递和MVVM中的ViewModel和界面之间的绑定, 因此MVC是最佳的选择。

 

转自:http://www.cnblogs.com/JustRun1983/p/3679827.html

相关文章
相关标签/搜索