#浅谈表现与数据分离 ##表现与数据分离是什么 伴随着一个程序的业务逻辑,会产生数据;数据从持久层抽出,经过一定逻辑,就会表现到程序界面上。一个程序在界面上的表现和保存下来的数据不应该是耦合的,数据应该可以对应多个表现界面。我们常说的表现与数据分离一般是指实现这个现象的技术,尤其是指一种代码组织的方式。 ##常用方式 `MVC`是我们经常听到的一种代码组织方式,用于使表现与数据分离。传统的MVC结合HTTP请求,把respone到浏览器的HTML全部算作为V。web2.0兴起后,在HTML上也包含着较多的业务逻辑,于是前端的MVC也逐渐产生,并有`MVVM`等新的针对于前端的代码组织方式及其他MV*框架。 ##回顾 之前我有谈及到传统MVC(以JavaEE的struts为例,见[这里](http://www.cnblogs.com/p2227/p/3551243.html))及我自己的在结合实现业务需求写的一个[js模板](http://www.cnblogs.com/p2227/p/3546725.html) ##比较 ###传统MVC struts这种传统的MVC,思路很清晰:你发起一个HTTP请求,我根据请求的数据及持久层查到的数据(M)把相应的HTML(V)respone到浏览器上,处理这两者关系的那一部分是控制器C,要拿出具体代码来应该是配置的XML及相应处理这个抽象逻辑的类。 ###前端MVC `angular`、`backbone`等前端的MVC,大体上也差不多。当然前端的话可以用另外一种方式:你发起一个Ajax请求,服务端返回一堆JSON数据(M),再根据特定的规则(C)表现到HTML上(V)。这些框架一个重要的特点是拥有`路由(Router)`的概念,这是他们能称为MVC框架的一个重要原因。 ###MVVM 以[`avalon`](http://rubylouvre.github.io/mvvm/)为例的MVVM框架,着力点在数据已经在前端之后,怎么样更好的展现成HTML及维持与用户的交互。前端MV*框架一般封装的是数据与视图的直接、双向的绑定,基本操作都比较单一,数据怎么变,表现层就跟着怎么变,而没有较复杂的逻辑关系。其实我们大多数的操作也就是需要一个简单的双向映射即可,业务的复杂我们应该细拆,用更加多的数据去描述,而不要把多个业务逻辑描述到一个数据(字段)上来。 ###jQuery 要对HTML操作就必然要用DOM。jQuery是操作DOM的首选js库,但以上没有一个MV*框架是基于jQuery的。我认为有三点原因 2. MV*框架针对单一的双向操作,jQuery针对复杂的逻辑操作。我们没必要去用一个庞大的Sizzle去选择到我们要操作的节点,再进行操作。MV*框架宣扬的是一种清晰的前端数据与表现分离思路,数据应该是有计划有目的地通过界面表现的,而不是突发奇想忽然而来的一个操作。 1. jQuery不针对文本节点和注释操作,看过源代码可知,nodeType===3 || nodeType===8的节点被jQuery抛弃了,而这些都是MV*框架打着旗号能操作的,所以原生的DOM操作会更加适合MV*框架。 3. 体积、效率、代码清晰度等其他方面的原因,你把jQuery引用起来,那jQ到底是属于哪方面的职责?违背MV*框架的初衷了。 ###js模板 本人写的[js模板](http://www.cnblogs.com/p2227/p/3546725.html),实质上是一个单向的MVVM框架,只考虑到了M->V的转换,其基本思路是:用数据分别去描述一段没有业务逻辑HTML模板和一些分散的业务逻辑,再用一段通用的逻辑代码去把它们组合在一起,形成HTML展现到界面上。缺少像avalon那样的scan方式,所以是做不到V->M的即时反馈的。 ##深入思考MV* MV*框架一般都定义好自己的扫描范围。像angular的ng-app、avalon主要是在scan的参数上。遍历DOM树寻找要绑定的数据及要展现数据的地方,否则白白浪费效率。 除了单一的双向数据绑定,MV*框架还会定义几种稍微复杂的数据表现约定。像 针对数组、针对函数、针对表格等,本质上还是制定一种约定:**数据只要按照这种方式去放置,我的框架就有一种内置的现成的表现形式,你就不用再去关注里面的业务逻辑了。**框架就是把各位码农每天重复写来写去而技术含量不高的操作(像CRUD)给抽象出来,帮我们从繁重的重复业务中解放出来,而更加关注一些核心的、较复杂的业务逻辑。 框架一般会给出一套事件绑定机制,让你去用它的事件。当然了,我们在input框中输入,那边的数据就立马改变,靠的必然是事件,如果用了这些框架还去自己定义事件,容易产生一些未知的错误。 引用[一篇国外的博文](http://addyosmani.com/blog/understanding-mvc-and-mvp-for-javascript-and-backbone-developers/),里面有提及到MVC的好处 * 易于维护 * 便于单元测试 * 剔除一些重复、低层的代码 * 分离了程序逻辑与表现界面,使得负责这两块的人可以同时工作 ##总结 再回到文章的标题,表现与数据分离是我们的目的,MVC、MVP还是MVVM,都只是一种手段。每一种语言每一个框架有其实现的具体细节。但总的思想就是:如何更好地组织代码,解决表现与数据分离的问题。如果不这么组织,后果可想而知:当需求变化时,我们无法估计要修改多少处代码,也无法估计修改后会产生多少的BUG,因为很多东西耦合在一起了,牵一发而动全身。我们也不一定要限制于这些代码约定好的组织方式,毕竟是开源的,可以根据自己当前的项目产品实质需求进行改造。我们也不能太依赖于框架,要看到低层的实现,对于开源软件也很容易处理。 ##参考 http://addyosmani.com/blog/understanding-mvc-and-mvp-for-javascript-and-backbone-developers/ http://www.dotblogs.com.tw/regionbbs/archive/2011/09/29/compare.to.mvp.mvc.mvvm.aspx