MVVM,也就是传说中的Model,ViewModel,View结构。自AngularJS开始大红大紫。
自MVC横空出世以来,对MVC的改进一直都没有停止过,MVC2, MVP, MVVM都号称是对MVC的改进,但其实MVC真的有什么问题要改进吗?MVC本身其实并没有什么缺陷,只不过是针对不同的应用场合,可以对MVC稍作变化,使得程序员的生产率更高些罢了,所以就出来了很多其他的MV*结构。
所有这些结构要解决的根本问题就是怎么把View和Model分开,View只管自己的UI部分,Model只管自己的数据部分,这样无论是改UI还是改数据,都比较轻松。
然而把VIew和Model分开之后,一个棘手的问题就是代码逻辑如何把View和Model再粘合起来,Model改变了要通知View拿新的数据,用户操作View让数据发生改变后代码逻辑要让Model能更新到新数据。于是对于这些逻辑操作的顺序的不同定义,产生了各种的MV*结构。
MVVM的精髓就在于ViewModel这一层,从名字就可以看出它这一层的作用就是用来给View和Model沟通的通道。ViewModel里面用的最核心的技术叫做双向绑定,也就是Model的任何改动,不需要任何的代码逻辑,就能直接反映到View上面,而View上的任何数据更新,不需要任何其他的代码逻辑,也能直接把Model给更新了。不像MVC,还得在Controller里写代码来通知更新,MVVM的更新是全自动的。
双向绑定不得不说是一个伟大的发明。然而,MVVM的全部好处也就仅限于此了。假如,从View到Model并不是仅靠简单的几行绑定代码就能搞定的,比如View的数据要经过复杂的业务逻辑转换后才能在Model上更新,那么这个时候,即便是绑定,也只能绑定一个用来转换的函数而已,所有的代码也必须自己在这个函数里写出来,如此一来MVVM就退化成MVC/MVP了。
可见,MVVM与MVP/MVC之间的距离,也就是一个双向绑定而已。
双向绑定虽然好,但是也有让人捉急的时候。ViewModel虽然名字叫ViewModel,但是却不能很容易的操作View。因为ViewModel的哲学是所有View里要用到的都需要双向绑定,所以对于没有绑定的View的元素,比如你要在View里加个div什么的,你会发现还是只能用JQuery去操作。这就是双向绑定的一个劣势,双向绑定在绑定静态内容上确实威风无比,但是在动态内容上就不太行了。一旦你用了JQuery,那么其实你的ViewModel就已经混杂Controller逻辑了。
MVVM还有个问题就是容易把ViewModel和Model混在一起。反正ViewModel里是绑定Model,何不把Model就写在ViewModel里面呢?这样显然是不利于维护的。
MVVM也容易被滥用,写架构的人把MVVM当成了神一样的存在,任何东西都试图给它搞一个MVVM出来。比如一个页面上可能几十个控件,每个控件他都要搞一个MVVM出来,定义出Model,ViewModel和View的3个文件。如此一来文件的数量一下子就激增了。加个简单的div也要改3个文件。而且当双向绑定绑定的东西太多的时候,性能会有所影响,特别是如果绑定了很多的事件回调,那么事件回调满天飞,很难debug到源头。MVVM这个其实是一个架构模式,而不是一个设计模式。用MVVM可以来做架构的设计,但是把它当成设计模式就是不对了。
这又让我想到了,在前公司培训的时候那个来自O记的项目经理一直在强调的每个method不超过30行。这种死板做法看似code是clean了,但是很容易造成文件数量大爆炸,如果改一个东西需要改很多个相关文件所带来的效率损失大于code clean所带来的效率提升,那实际上是得不偿失的。真正的clean code并不在method的行数。
最后我想说一下Model,但也并不限于MVVM。Model到底应该不应该包含代码逻辑,到底应该不应该把Model做成只有纯粹的数据?Model如果不包含代码逻辑,那么一个简单的类比就是Java的POJO,只有get和set方法。这样的好处是Model异常简单明了。但坏处是对Model操作的所有逻辑都在Controller/ViewModel里面,导致Controller/ViewModel异常臃肿,这也就是所谓的贫血模型。肯定有人会agrue说这样才是最清晰完美的分层。这没错,但是分层并不是OO。Model里面没有任何逻辑操作的话,也就不能qualify为一个OO的object。一个不OO的design,Controller/ViewModel这一层写起来估计是十分痛苦的。如果想要OO,那么Model里应该包含和Model自身相关的操作逻辑,这就是所谓的充血模型。但这样Model就会显的不清晰,和Controller/ViewModel之间的调用接口也没有分层那样清楚了。所以如何design,其实说到底就是个balance的问题。
网友评论