美文网首页
MVC,MVP,MVVM区别

MVC,MVP,MVVM区别

作者: yong_history | 来源:发表于2017-02-27 11:38 被阅读0次

    一. MVC,MVP和MVVM诞生需求

    MVC,MVP和MVVM都是用来解决界面呈现和逻辑代码分离而出现的模式。
    软件中最核心的,最基本的东西是什么?是的,是数据。我们写的所有代码都是围绕数据的产生,修改等变化出现了业务逻辑。
    一般的代码结构从上到下依次是视图层,业务逻辑层和数据层,而MVC、MVP和MVVM都是来解决视图层和业务逻辑层的耦合。

    二. MVC模式

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。MVC开始是存在于桌面程序中,使用MVC的目的是将M和V的实现代码分离。

    2.1 主动MVC

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

    Model

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

    View

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

    Controller

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

    220950360131856.png

    2.2 被动MVC

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


    220950371071953.png
    被动MVC与主动MVC的区别:
    1. 模型对视图和控制器一无所知,仅仅是被他们使用
    2. 控制器使用视图,并通知它更新数据显示
    3. 视图仅仅是在控制器通知它去模型取数据的时候它才这么做(视图并不会订阅或监视模型的更新)

    2.3 MVC优点

    *耦合性低
    *开发速度快
    *可维护性高

    2.4 MVC使用的误区

    1. 把Model理解成实体类(Entity),在MVC中Model应该包含2部分功能,一部分是处理业务逻辑,一部分是提供View显示的数据
    2. 把业务逻辑全部放在Controller中
      这两个误区本质上都是对Model的作用不明导致的
      Model在MVC架构中起的作用非常重要,他应该是业务逻辑真正的实现层。所以Model实际上是Business Model(业务模型),而Controller仅仅起一个“桥梁”的作用,它负责把View的请求转发给Model,再负责把Model处理技术的消息通知View。Controller是用来解耦View和Model的

    2.5 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。

    原文链接:http://www.cnblogs.com/JustRun1983/p/3679827.html

    三、MVP模式

    MVP模式也是一种经典的界面模式。MVP中的M代表Model,V是View,P是Presenter。

    3.1 MVP的思想

    MVP模式在我看来,是一个真正意义上的隔离View细节和复杂性的模式。为什么这么说呢?
    因为在其它模式中V都代表的是UI界面,但是在MVP模式中代表的是一个接口,一个将UI界面提炼而抽象出来的接口。接口意味着任何实现了该接口的界面,都能够复用已有的Presenter和Model代码

    3.2 UI界面接口化

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

    141349045464079.png
    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属性的操作了,也就是和具体的界面显示无关了。

    3.3 Presenter-Model和View之间的桥梁

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

    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); 
       }
    }
    

    3.4 MVP的代码结构和时序图

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

    141349081564481.png 141349138756727.png

    3.5 MVP模式总结

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

    MVP的优势

    1. 模拟与视图完全分离,我们可以修改视图而不影响模型
    2. 可以更高效的使用模型,因为所有的交互都发生在一个地方-Presenter内部
    3. 我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
    4. 如果我们把逻辑放在Presenter中,那么我们就可以脱离用户界面来测试这些逻辑(单元测试)

    四、MVVM模式

    4.1 MVVM模式的设计思想

    MVVM模式中,一个ViewModel和一个View匹配,它没有MVP中的IView接口,而是完全的和View绑定,所有View中的修改变化,都会自动更新到ViewModel中,同时ViewModel的任何变化也会自动同步到View上显示。
    这种自动同步之所以能够的原因是ViewModel中的属性都实现了observable这样的接口,也就是说当使用属性的set方法,都会同时触发属性修改的事件,使绑定的UI自动刷新。
    所以MVVM比MVP更升级一步,在MVP中,V是接口IView,解决对于界面UI的耦合;而MVVM干脆直接使用ViewModel和UI的无缝结合,ViewModel直接就能代表UI。但是MVVM做到这点是要依赖具体的平台和技术实现的,这也就是为什么ViewModel不需要实现接口的原因,因为对于具体平台和技术的依赖,本质上使用MVVM模式就是不能替换UI的使用平台

    4.2 MVVM模式结构图

    这里是MVVM模式的结构图,能够帮助更加容易的理解MVVM模式

    141349167032958.jpg

    来源:http://www.cnblogs.com/JustRun1983/p/3727560.html

    相关文章

      网友评论

          本文标题:MVC,MVP,MVVM区别

          本文链接:https://www.haomeiwen.com/subject/tfrwwttx.html