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是整个系统的核心部分,上面这幅图就是这样的,还有的方案把业务逻辑直接放到了Controller中,Model只负责处理数据。而且在不同的方案中,要么View与Controller耦合过于紧密,要么View访问Model的时候比较低效,要么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模式

时间: 2024-10-09 08:38:06

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

uwp开发:MVVM模式和数据绑定结合使用实战示例

——我的<简影uwp>开发了一段时间了,现在各个板块和基本功能已经完工,剩下的就是细节方面的处理和UI排版设计了.开发期间遇到过很多问题,由于是个人独立开发.所以好多问题需要自己想好长时间,或者去网上寻找大神求助,有时候晚上做梦都是满脑子的代码.好的是大部分最终都解决了!真的非常感谢那些帮助我的大神们,和他们交流,我学到了很多... 好了,闲话不多说,前几天,我处理的是集合数据绑定的问题,也就是说返回的是一个集合数据,用MVVM模式来说,让ViewModel层实现ObservableColle

JavaScript大杂烩0 - WEB基础知识

1. 协议小结:HTTP协议与TCP/IP协议 现代Web应用开发的基础是HTTP协议,那么HTTP协议与我们熟知的TCP/IP协议有什么关系呢? 这个要从网络通信模型说起,简单的说,计算机通信就像两个人在互相交流,怎样才能互相听懂呢?很简单,就是使用一致的语言和表达方式. 计算机之间通信的语言就是网络协议.网络协议是网络上所有设备(网络服务器.计算机及交换机.路由器.防火墙等)之间通信规则的集合,它规定了通信时信息必须采用的格式和这些格式的意义.大多数网络都采用分层的体系结构,比如传统的开放式

学JavaScript,做web开发

有一天我被问到,为了快速地在 web 开发工作上增加优势,应该学习什么语言.我的思绪回到了在麦子学院学习的时光,那时候我用 Pascal.Fortran.C和汇编语言,不过那个时候有不同的目标. 想做web开发,就学JavaScript 鉴于当前的状况和趋势,答案相对容易给出来:学习 JavaScript.四周看看,曾经低端的浏览器脚本语言现在变得随处可见,从服务器端到客户端,每天好像有更多的选择. 出身低微 我记得数年前投入 web 开发,学习了 HTML.用 Perl 开发 CGI 脚本.N

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

随着前端Ajax兴起.前端开发工作进一步划分:js开发和ui页面制作.另外从整个前端项目的清晰明朗以可扩展性角度来看,MVC的应用也越来越必要,特别是对大的项目. 例如 需要给一个页面上的button注册一个onclick事件. 1.我们可以有如下最简洁的写法:(view和model control完全混合) <HTML> <HEAD> <TITLE> example </TITLE> </HEAD> <BODY> <input

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

在触屏设备上,一些比较基础的手势都需要通过对 touch 事件进行二次封装才能实现.zepto 是移动端上使用率比较高的一个类库,但是其 touch 模块模拟出来的一些事件存在一些兼容性问题,如 tap 事件在某些安卓设备上存在事件穿透的 bug,其他类型的事件也或多或少的存在一些兼容性问题. 于是乎,干脆自己动手对这些常用的手势事件进行了封装,由于没有太多真实的设备来进行测试,可能存在一些兼容性问题,下面的代码也只是在 iOS 7.Andorid 4 上的一些比较常见的浏览器中测试通过. ta

基于Web开发模式的信息抽取

基于Web 开发模式的信息抽取 信息抽取是一个互联网自然语言处理的一个首要环节,信息抽取的准确度会直接影响到后续的处理.信息抽取的目标是去除噪音,获取网页有价值的信息如网页的标题.时间.正文.链接等信息.   主流算法介绍 网页信息抽取的方法有很多,比如从算法上分:基于模板的,基于信息量.基于视觉的.基于语义挖掘的.基于统计的.从HTML 处理上分为:基于行块.基于DOM 树.下面我逐一介绍. 1.     基于模板,一般由人工维护一个URL 和HTML 的模板.当URL 匹配到某个URL 模板

Python学习教程:WEB开发——Python WSGI协议详解

Web应用程序开发 Web应用程序的本质是什么 简单描述Web应用程序的本质,就是我们通过浏览器访问互联网上指定的网页文件展示到浏览器上. 流程如下图: 从更深层次一点的技术角度来看,由以下几个步骤: 浏览器,将要请求的内容按照HTTP协议发送服务端 服务端,根据请求内容找到指定的HTML页面 浏览器,解析请求到的HTML内容展示出来 HTTP协议的全称是HyperText Transfer Protocol(超文本传输协议) HTTP协议是我们常用的五层协议中的应用层(5层从上到下是应用层,传

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

MVC,MVP和MVVM都是常见的软件架构设计模式(Architectural Pattern),它通过分离关注点来改进代码的组织方式.不同于设计模式(Design Pattern),只是为了解决一类问题而总结出的抽象方法,一种架构模式往往使用了多种设计模式. 要了解MVC.MVP和MVVM,就要知道它们的相同点和不同点.不同部分是C(Controller).P(Presenter).VM(View-Model),而相同的部分则是MV(Model-View). Model&View 这里有一个可

熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。

熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验. 1.说一说Servlet生命周期(非常重要) Servlet生命周期包括三部分: 初始化:Web容器加载servlet,调用init()方法 只执行一次 处理请求:当请求到达时,运行其service()方法.service()自动调用与请求相对应的doXXX