JavaScript大杂烩18 - Web开发的MVVM模式
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模式的更多相关文章
- JavaScript大杂烩0 - WEB基础知识
1. 协议小结:HTTP协议与TCP/IP协议 现代Web应用开发的基础是HTTP协议,那么HTTP协议与我们熟知的TCP/IP协议有什么关系呢? 这个要从网络通信模型说起,简单的说,计算机通信就像两 ...
- 简单理解前端web开发的MVC模式
随着前端Ajax兴起.前端开发工作进一步划分:js开发和ui页面制作.另外从整个前端项目的清晰明朗以可扩展性角度来看,MVC的应用也越来越必要,特别是对大的项目. 例如 需要给一个页面上的button ...
- Web开发中 MTV模式与MVC模式的区别 联系 概念
MTV 与 MVC模式的区别 联系 概念: MTV: 所谓MTV指的就是: M:model (模型),指的是ORM模型. T:template (模板),一般Python都是使用模板渲染的方式来把HT ...
- python web开发-flask调试模式
使用run()方式可以启动flask应用,但是每次修改代码之后,需要重新启动,这样对于调试就很不太方便.Flask的调试模式可以让代码在每次修改之后自动载入. 有两种方法可以启用flask的调试模式 ...
- javascript移动设备Web开发中对touch事件的封装实例
在触屏设备上,一些比较基础的手势都需要通过对 touch 事件进行二次封装才能实现.zepto 是移动端上使用率比较高的一个类库,但是其 touch 模块模拟出来的一些事件存在一些兼容性问题,如 ta ...
- 【转】十步让你成为一名优秀的Web开发人员
第一步:学好HTML HTML(超文本标记语言)是网页的核心,因此你首先应该学好它,不要害怕,HTML很容易学习的,但也很容易误用,学懂容易要学精还得费点功夫,但学好HTML是成为Web开发人员的基本 ...
- 了不起的Node.js: 将JavaScript进行到底(Web开发首选,实时,跨多服务器,高并发)
了不起的Node.js: 将JavaScript进行到底(Web开发首选,实时,跨多服务器,高并发) Guillermo Rauch 编 赵静 译 ISBN 978-7-121-21769-2 2 ...
- 浅析前端开发中的 MVC/MVP/MVVM 模式
MVC,MVP和MVVM都是常见的软件架构设计模式(Architectural Pattern),它通过分离关注点来改进代码的组织方式.不同于设计模式(Design Pattern),只是为了解决一类 ...
- Web开发——JavaScript基础
参考学习: MDN JavaScript:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript ECMAScript 6入门(阮一峰):htt ...
随机推荐
- Spring Boot整合 Thymeleaf 模板引擎
什么是Thymeleaf Thymeleaf是一款用于渲染XML.XHTML.HTML5内容的模板引擎.类似Velocity,FreeMaker模板引擎,它也可以轻易的与Spring MVC等Web框 ...
- php 对中文字符串的处理- 随机取出指定个数的汉字
mb_internal_encoding("UTF-8"); $str="们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在岭骗休借了不和有大这主中人上为来分生 ...
- 无源码调试smali
0x01 工具①Android Studio最新版.(用的1.5)②apktool尽量使用最新版的.(反编译本人用baksmali-2.1.3.jar)③smalidea插件.下载地址https ...
- mybatis随笔五之Executor
在上一篇文章我们分析到了mapper接口方法的实现实际上是交由代理类来实现的,并最终调用Executor来查询,接下来我们对executor.query(ms, wrapCollection(para ...
- 基于Flume的日志收集系统方案参考
前言 本文将简单介绍两种基于Flume的日志收集系统可能的架构方案,可根据不同的实际场景参考使用. 方案一 示例图如下: 说明: 每个日志源(http上报.日志文件等)对应一个Agent-c用于收集对 ...
- Spring Cloud Consul使用——服务注册与发现(注册中心)
整理自该文章 一.Consul 服务端接下来我们开发 Consul 的服务端,创建一个 spring-cloud-consul-producer 项目 1.添加依赖包 <dependencies ...
- Linux常用命令-vim
vim的基本模式 1普通模式Normal mode 输入vim命令后进入的就是普通模式. 2插入模式Insert mode 这是内容修改编辑的模式, 在普通模式进入插入模式方法 按i或insert 在 ...
- 无法启动MYSQL服务”1067 进程意外终止”解决的方法
自己一開始依照百度经验里的方法——<MySQL下载安装.配置与使用(win7x64)>去安装和配置,可是到后面步骤总是出现1067代号的错误. 慢慢折腾去解决. 这里汇总各种导致mysql ...
- java使用java.lang.management监视和管理 Java 虚拟机
ClassLoadingMXBean 用于 Java 虚拟机的类加载系统的管理接口. CompilationMXBean 用于 Java 虚拟机的编译系统的管理接口. GarbageCollector ...
- 获取DNS服务器的版本信息
1 如何获取DNS服务器的版本信息 向某个DNS服务器发送下面的请求即可获得版本信息 dig @115.124.17.156 version.bind chaos txt 它返回的信息如下: ; &l ...