MVC VS. MVP VS. MVVM 
  了解MVVM模式之前,我们先来简单了解一下从MVC到MVVM的变迁。这个变迁是耦合从紧到松的变迁,是对依赖处理的进化,是应对变化技术的成熟。

MVC 
  MVC全名是Model View Controller, 是模型(model)-视图(view)-控制器(controller)的缩写,它用一种将业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。将系统进行MVC分层的核心思路就是分离组件,降低组件耦合性,组件独立演化。 
  MVC模式可以使用下面这幅图来描述各个部分的作用以及与其他组件的交互过程: 

  MVC模式的优点很明显,那就是耦合性低,重用性高,应对每个组件的变化性好,便于开发,测试与维护。但是MVC模式也还是有缺点的,给系统带来的额外复杂性自然不必说了,此外,MVC三个组件的定义存在一定的模糊性,这样就衍生了很多的比如主动MVC,被动MVC等实施方案,每种方案中MVC三大组件的功能都不太一样,比如有的把业务逻辑放到Model部分,Controller只不过是把用户输入转换一下,直接传给Model来处理,Model是整个系统的核心部分,上面这幅图就是这样的(这种情况其实就是真正的MVC模式的定义),还有的方案把业务逻辑直接放到了Controller中,Model只负责处理数据。而且在不同的方案中,要么View与Controller耦合过于紧密,要么View访问Model的时候比较低效,要么Model由于要与View直接打交道,导致了Model与View直接耦合在了一起,而Model发生变化的时候会牵连View一起变化,这却恰恰违背了MVC组件分层的本意。

MVP 
  MVP的全称为Model-View-Presenter,Model提供数据,View负责显示,Presenter负责逻辑的处理。MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过Controller。 
  MVP模式可以使用下面这幅图来描述各个部分的作用以及与其他组件的交互过程: 

  在MVC里,我们谈到它的缺点主要有两个: 
  一个是MVC三大组件的定义比较模糊。这个在MVP中就相对明确一些了:Model只负责处理最终数据;View就是很薄的一层,只显示数据,通常认为,View只应该有简单的Set/Get的方法,View只负责用户输入和设置界面显示的内容,除此就不应该有更多的内容,绝不容许直接访问Model;所有业务逻辑都由Presenter处理,而且,Presenter与具体的View和Model是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View或者Model具体实现的时候可以保持Presenter的不变,这样就实现了业务逻辑的重用。 
  另一个是View与Model的紧密耦合。在MVC中,View是可以直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。 在MVC模型里,更关注的Model的不变,而同时有多个对Model的不同显示,及View。所以,在MVC模型里,Model不依赖于View,但是View是依赖于Model的。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的。 
  在现实中,MVP的实现会根据View的充、贫血而有一些不同,一部分倾向于在View中放置简单的逻辑,在Presenter放置复杂的逻辑;另一部分倾向于在presenter中放置全部的逻辑。这两种分别被称为:Passive View和Superivising Controller。 
  在Passive View中,为了减少UI组件的行为,使用Controller不仅控制用户事件的响应,而且将结果更新到View上。可以集中测试Controller,减小View出问题的风险。 
  在Superivising Controller中的Controller既处理用户输入的响应,又操作View处理View的复杂逻辑。

  MVP解决了MVC的一些问题,其实现在说到MVC,通常指的也就是MVP。但是MVP也是不完美的,由于Presenter可以反作用于View,这样View的渲染有可能就放在了Presenter中,所以View和Presenter的交互会过于频繁。如果Presenter过多地渲染了View,往往会使得它与特定的View的联系过于紧密。一旦View需要变更,那么Presenter也需要变更了。

MVVM 
  MVVM全称Model-View-ViewModel,Model提供数据,View负责显示,这个还和MVP一样,这个模式的重点就是ViewModel的部分,它通过双向绑定(松耦合)解决了MVP中Presenter与View联系比较紧密的问题。 
  MVVM模式可以使用下面这幅图来描述各个部分的作用以及与其他组件的交互过程: 

  从图中我们可以看到MVVM与MVP最大的不同就在于View与ViewModel交互的时候使用了松耦合的双向绑定,而不是像View与Presenter那样直接交互。ViewModel作为View的数据映射,通常View上有什么属性,ViewModel上也会存在相应的一个属性,这两个属性通过事件实现了双向的绑定,常见的MVVM框架都替我们完成了这样的绑定过程。 
  MVVM最初是微软在WPF中实现的模式,随之在Web开发中也开始了MVVM风潮,这里介绍的3个MVVM框架就是我认为比较典型的几个。

微软的前端框架knockoutjs 
  这是一个独立的前端MVVM框架,也是最早的前端MVVM框架,它完成了页面的数据与界面之间的双向绑定,至于真正这些数据是通过何种手段(比如Ajax)获取到的,它并不关心。这是一个只关注前端逻辑与界面解耦的纯前端类库,理论上可以搭配任何的后台技术,来完成整个网站的建设。这是我第一个学习的MVVM框架,使用它给我的感觉是相当良好:绑定好了自动双向更新是多么酷的特性啊。

下面是比较火热的几个学习教程: 
http://knockoutjs.com/ 
http://www.cnblogs.com/TomXu/archive/2011/11/21/2257154.html 
http://www.cnblogs.com/lori/p/3552571.html

谷歌的全套服务angularjs 
  这是一个比较庞大,但是也无比强大的前端MVVM类库,天生对RESTful API的良好支持,双向绑定的优良特性,专业的HTML模板扩展支持,全面的测试框架,与Bootstrap,Nodejs的完美融合,再加上Google的金字招牌,你可以拒绝么?

下面是比较火热的教程: 
https://angularjs.org/ 
http://www.ituring.com.cn/minibook/303 
http://www.iteye.com/news/28651-AngularJS-Google-resource 
http://woxx.sinaapp.com/ 
http://www.angularjs.cn/tag/AngularJS

最迷你的MVVM框架avalon 
  这确实是最mini的MVVM框架,与Angularjs不一样,它侧重数据结构的设计,提倡简单的算法,它是在吸收上面两个类库的基础上发展起来的,而且符合国情,支持IE6,难道不值得期待?

下面是比较好的教程: 
http://rubylouvre.github.io/mvvm/ 
http://limodou.github.io/avalon-learning/zh_CN/index.html 
http://www.cnblogs.com/rubylouvre/p/3181291.html 
http://www.oschina.net/p/avalon 
http://www.iteye.com/topic/1130359 
http://www.tuicool.com/articles/NrMrIn

最后附送一个有意思的网站:http://todomvc.com/,自己研究一下吧。

JavaScript大杂烩18 - Web开发的MVVM模式的更多相关文章

  1. JavaScript大杂烩0 - WEB基础知识

    1. 协议小结:HTTP协议与TCP/IP协议 现代Web应用开发的基础是HTTP协议,那么HTTP协议与我们熟知的TCP/IP协议有什么关系呢? 这个要从网络通信模型说起,简单的说,计算机通信就像两 ...

  2. 简单理解前端web开发的MVC模式

    随着前端Ajax兴起.前端开发工作进一步划分:js开发和ui页面制作.另外从整个前端项目的清晰明朗以可扩展性角度来看,MVC的应用也越来越必要,特别是对大的项目. 例如 需要给一个页面上的button ...

  3. Web开发中 MTV模式与MVC模式的区别 联系 概念

    MTV 与 MVC模式的区别 联系 概念: MTV: 所谓MTV指的就是: M:model (模型),指的是ORM模型. T:template (模板),一般Python都是使用模板渲染的方式来把HT ...

  4. python web开发-flask调试模式

    使用run()方式可以启动flask应用,但是每次修改代码之后,需要重新启动,这样对于调试就很不太方便.Flask的调试模式可以让代码在每次修改之后自动载入. 有两种方法可以启用flask的调试模式 ...

  5. javascript移动设备Web开发中对touch事件的封装实例

    在触屏设备上,一些比较基础的手势都需要通过对 touch 事件进行二次封装才能实现.zepto 是移动端上使用率比较高的一个类库,但是其 touch 模块模拟出来的一些事件存在一些兼容性问题,如 ta ...

  6. 【转】十步让你成为一名优秀的Web开发人员

    第一步:学好HTML HTML(超文本标记语言)是网页的核心,因此你首先应该学好它,不要害怕,HTML很容易学习的,但也很容易误用,学懂容易要学精还得费点功夫,但学好HTML是成为Web开发人员的基本 ...

  7. 了不起的Node.js: 将JavaScript进行到底(Web开发首选,实时,跨多服务器,高并发)

    了不起的Node.js: 将JavaScript进行到底(Web开发首选,实时,跨多服务器,高并发) Guillermo Rauch 编   赵静 译 ISBN 978-7-121-21769-2 2 ...

  8. 浅析前端开发中的 MVC/MVP/MVVM 模式

    MVC,MVP和MVVM都是常见的软件架构设计模式(Architectural Pattern),它通过分离关注点来改进代码的组织方式.不同于设计模式(Design Pattern),只是为了解决一类 ...

  9. Web开发——JavaScript基础

    参考学习: MDN JavaScript:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript ECMAScript 6入门(阮一峰):htt ...

随机推荐

  1. 嵌入式小系统I2S接口调试总结

    最近调试了I2S.由于芯片里面硬件配置出现了几个错误,着实也把我折腾了一番,不过,最终 还是把它搞定了.为了加深理解,就做个笔记吧,方面以后查找和学习. 定义:I²S或I2S(英语:Inter-IC ...

  2. LeetCode:144_Binary Tree Preorder Traversal | 二叉树的前序遍历 | Medium

    题目:Binary Tree Preorder Traversal 二叉树的前序遍历,同样使用栈来解,代码如下: struct TreeNode { int val; TreeNode* left; ...

  3. LeetCode--No.014 Longest Common Prefix

    14. Longest Common Prefix Total Accepted: 112204 Total Submissions: 385070 Difficulty: Easy Write a ...

  4. 1 认识Jquery

    一 代码风格和变量风格 1 链式操作风格 : (1)对同一对象不超三个操作的可以写在一行 (2)对于同一个对象的较多操作,建议每行写一个操作 (3)对于多个对象的少量操作,可以每个对象写一行,涉及子元 ...

  5. Hadoop生态系统之Yarn

    Apache YARN(Yet Another Resource Negotiator) 是Hadoop的集群资源管理系统.YARN被引入Hadoop2最初是为了改善MapReduce的实现,但它具有 ...

  6. Linux内核源码分析之调度、内核线程模型 And Centos7.2's Kernel Resource Analysis

    本文分为概述.历史.el7.2代码架构图解三部分. 解决的问题: a.Kernel调度发展过程: b.以架构图的方式,详解el7.2具体调度实现.内核线程模型.调度时间片计算,以及探究整个Kernel ...

  7. MySQL 5.6 GTID Replication

    一. MySQL 5.6引入了GTID的概念,那么GTID是何方神圣?其实也不复杂,就是一个全局事务标示符.使用GTID时,每次事务提交都会在binlog里生成1个唯一的标示符,它由UUID和事务ID ...

  8. virtualBox安装centos,并搭建tomcat

    前言 本文没什么难点,只是发现自己记忆不好,特别是搭建tomcat服务的时候,总是需要去重新查阅资料,特此就写这篇博客来加强自己的记忆,同时也给大家以参考: 路漫漫其修远兮,吾将上下而求索! gith ...

  9. NFS部署教程

    NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NFS的客户端应用可 ...

  10. ThreadPoolExecutor代码解析

    派生体系 java.util.concurrent ThreadPoolExecutor AbstractExecutorService ExecutorService Executor   这个类是 ...