关于MV*模式的一己之见,科普向

643 阅读6分钟

一直对mv*模式不太了解,终于趁着周末闲暇之余试着去理解了以下,以下是个人总结,欢迎讨论,如有错误请指教。

传统mvc

mvc是一套设计模式的组合,最初是用于解决客户端图形界面应用程序的模块化问题。

由于用户界面逻辑的更改往往要比业务逻辑更频繁,并且在某些情况下,应用程序需要以不同的方式来显示同一数据等...诸多问题下,解决方案mvc就此诞生。

Model-View-Controller (MVC) 将程序划分为三层

  • 模型 model封装了程序指定的数据和逻辑(数据与业务)

  • 视图 view是对数据的显示(界面)

  • 控制器 controller能够响应用户操作来通知model进行更新(只是通知,真实处理是由model自身执行)或者view的更新(事件)

model不只是数据的整合,还包含了对数据进行处理的能力。

三者依赖和调用关系可以参考下图,主要是懒得画。

依赖:可以很明确的看到view和controller都依赖于model。

调用:

1. view接收到输入,转发给controller
2. controller 对输入进行预处理后,调用匹配的model接口
3. model执行业务逻辑,变更数据后通过观察者/订阅模式通知所有已注册的观察者(view)
4. view收到model变更通知,请求更新后的数据,更新界面

关于调用关系可以看出,mvc主要由观察者模式构筑,策略模式(controller可以算作view的策略之一)以及其他模式作为辅助

依赖关系可以在调用流程中得到验证,view由于是直接向model请求数据并更新的,所以view实质上是知道model内数据的相关结构的,controller同理。这就导致了view与controller无法脱离model,并且不可在其他程序内部复用。

被动mvc

时代的发展,导致现在web应用的大行其道。

与客户端图形界面程序不同,web应用主要是通过http协议进行通信,但http协议是单工协议并且是无状态的,服务器无法直接给客户端推送数据,这也就导致了view订阅model更新的模式被打破。

变更后web应用mvc模式大致流程为:

1. 客户端发送请求
2. 服务端通过路由调用相应的controller ,对来自客户端得请求进行格式化预处理然后调用相应的 model 接口
3. model执行业务逻辑,使用数据渲染模版视图,服务器回复请求
5. 客户端更新

演化

mvp

由于mvc模式下的view与model的高度耦合,view无法被组件化,复用程度低,所以mvp被提出

mvp直接切断了view和model的绑定关系,解除了二者的耦合。

controller 被替换(重命名)成了 presenter

mvp调用改变为:

1. view接收到输入,转发给presenter
2. presenter对输入进行预处理后,调用匹配的model接口
3. model执行业务逻辑,变更数据后通过观察者模式通知presenter
4. presenter获取更新后的数据,通过view提供的更新接口更新进行界面更新

实质上mvp就是mvc的另一形式,presenter相比controller包含了更多的逻辑变得厚重(接受model的变更通知,与更新view的能力)。而view不再依赖model,对于model以及presenter内的数据与业务完全无感知,所以view可以被抽象用于不同的应用中,只要提供对应的接口。

mvvm

mvvm是mvp的改良版,相对于mvp而言,在依赖关系上与调用关系上都没有什么变化,所以就不放图了:)

mvp相比mvc来说,它抽离了view提高了模块化程度,但presenter层既承担了对view事件的预处理,又需要提供对于view的数据同步,导致了逻辑过于繁琐厚重,难以开发与维护。

于是Model-View-ViewModel被提出,vm承载了presenter的功能,并且将model与view之间的数据更新抽离出来,提供了自动化的能力,开发人员不必再手动维护model与view之间的更新逻辑,可以更专注于核心业务的开发。

mvc => mvp => mvvm 模式的更新,本质上是由于项目复杂度不断增加,新的需求被不断被提出,为了维持现状而被迫的升级改良。

新模式这方面,新模式是不可能有新模式的,这辈子不可能有新模式的。换模式又不会搞,就是改良模式这种东西,才能维持的了生活这样子。

前端

终于到前端了,作为本职工作,前端战五渣,虽然不懂,但还是要勉强一写,关于模式的理论在上文中已经大致介绍了一遍,下面只是一些关于模式与前端框架的杂谈。

前端框架与库千千万,模式却不多,也就mvc与mvvm占主流。

Angular与Vue可以算是主流的mvvm框架/库,由于Angular只是浅显的走过一次教程所以就不提了。

Vue

关于Vue,在我看来,框架自身可以算是一层vm,至于我们写的模版,自然是view。但有很多人认为model应该是data也就是数据。但我认为,开发人员所写的js大多都属于model。

Vue的实现可以分为两步,对数据的劫持与解析dom后的数据监听(订阅者),实现了一套data=>view,view=>data的关系,用于自动化处理数据,开发者无需关注dom的更新,只需要为对应的事件来编写匹配的,用于更新data的函数即可(包含了ajax对于后端的请求)。

前后端分离的模式下,后端基本上只需要提供RESTful API即可。

React

React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。

React应该是一个属于mvc的视图库,功能非常简单而纯粹,根据state渲染view。

关于react没有多写,第一是感觉言尽于此,描述的挺清楚的。其次是因为写这篇总结纯属意外,本来前两天在看一些flux实现与redux源码(才四五百行,注释都还写的挺清楚,对react有兴趣的朋友可以看看)然后莫名其妙就开始看mvc相关内容,跑偏了,后面就放弃治疗了。

如果有机会的话,下一篇估计会写关于flux=>redux的文章,react留到下一篇再聊。


参考资料如下。

微软msdn:MVC模式

阮一峰:谈谈MVC模式

阮一峰:MVC,MVP 和 MVVM 的图示

百度文库:深入浅出设计模式之MVC

界面之下:还原真实的MV*模式