关于MVC、MVP、MVVM这几种架构方式的理解。
前人种树,后人乘凉。关于MVC、MVP、MVVM这几种架构方式的理解,前辈们写了很多的解答,我结合几篇好文,总结了以下一点点内容。
软件的架构方式有很多种,从最开始的MVC模式,到MVP,然后到现在的MVVM,在不断的演化过程中其核心的思想就是降低各组件之间的耦合度,使得数据的流向更加的清晰明了。但并不是意味着一个比另一个高级,只是对于软件的架构方式有的不同的视角,针对不同的场景有了更多的选择方案。那么,软件架构到底是什么呢,他有什么作用呢?其实,架构就相当于人的骨架,他决定了软件开发之后所有的操作是基于一种什么样的方式进行的,因此,他对于开发是至关重要的。
(Model-View-Controller)
和(Model-View-ViewModel)
在概念上都是基于分层的,将表现与数据分开的设计架构,M 和 V 基本上不是问题,但将这两个整合的中间这层可就有很多的学问,另外,除了 MVC 和 MVVM 外,还有一个叫做 MVP (Model-View-Presenter)
的架构,这三个的设计概念非常类似,很容易会让人傻傻分不清楚……
我们先来看各个架构的设计原则好了。
首先是 MVC,顾名思义,MVC 是将 Model、View 和 Controller 分离,让彼此的职责能够明确的分开,这样不论是改 M、 V 还是 C,都可以确保另外两层可不用做任何修改,同时这样的分层也可以加强程序的可测试性,View 和 Model 基本上是相关的,但它们并不会有直接的相依关系,而是由 Controller 去决定 Model 产生的数据,然后丢给 View 去做呈现,也就是说,Controller 是 Model 和 View 之间的协调者,View 和 Model 不能直接沟通,以确保责任的分离。
顺便贴一张关于前后端MVC架构的图片
MVC模式最初生根于服务器端的Web开发,后来渐渐能够胜任客户端Web开发,能够满足其复杂性和丰富性。 MVC模式的特点在于实现关注点分离,即应用程序中的数据模型与业务和展示逻辑解耦。在客户端web开发中,就是将模型(M-数据、操作数据)、视图(V-显示数据的HTML元素)之间实现代码分离,松散耦合,使之成为一个更容易开发、维护和测试的客户端应用程序。
优点
缺点
首先控制器接收用户的请求,并决定应该调用哪个模型来进行处理,然后模型用业务逻辑来处理用户的请求并返回数据,最后控制器用相应的视图格式化模型返回的数据,并通过表示层呈现给用户。
再来是 MVVM,MVVM 的架构一样是 M、V 分离,但中间是以 VM (ViewModel) 来串接,这个 ViewModel 比较像是 View 的一个代理程序,它负责直接对 Model 做沟通,而 View 可以透过一些机制 (例如: Events,Databindings…) 来和 ViewModel 沟通以取得数据或将数据抛给 Model 做存取等工作,ViewModel 也可以作为和外部系统的代理程序,例如 Web Service 或是 REST Service 或是 Enterprise Services 等等,不过它和 MVC 不同的地方,就是 ViewModel 和 View 的黏合度比较高,因为 View 必须要透过 ViewModel 才可以取得 Model,而 ViewModel 又必须要处理来自 View 的通知讯息,所以虽然职责一样分明,但是却不像 MVC 那样可以扩展到整个系统组件都能用。如果 MVVM 要和 MVP 比较的话,MVVM 会比 MVP 更灵活一点。
MVVM其实是对MVP的一种改进,他将Presenter替换成了ViewModel,并通过双向的数据绑定来实现视图和数据的交互。也就是说只需要将数据和视图绑定一次之后,那么之后当数据发生改变时就会自动的在UI上刷新而不需要我们自己进行手动刷新。在MVVM中,他尽可能的会简化数据流的走向,使其变得更加简洁明了。
优点
缺点
接着是 MVP,MVP 一样也是职责分明,且 Model 与 View 分离的架构,但是这个 P (Presenter) 和 ViewModel 就很类似,不过就如同 Presenter (主持人) 这个字所代表的意义,所有主控 View 呈现的工作,都是由 Presenter 来做,而 View 本身只是 Presenter 所要使用的舞台而已,所以 View 原则上会相依于 Presenter,但是为了要做到关注点分离 (SoC 原则),所以在 View 和 Presenter 间都会加入一个界面 (例如: IView),然后以 IoC 的方式将 View 注射到 Presenter 中,而 Presenter 就使用接口所定义的方法去操控,而 View 就透过接口所定义的方法去呈现接口即可。但也因为受限于接口,所以 Presenter 只能依接口定义的动作去响应与处理,而不能再做更多的延伸功能,除非更改 View 的接口。
优点
缺点
以上的解释是不是看蒙圈了,OK,我又发现一篇(作者:这是你的玩具车吗)博文里面写的讲解,发现挺容易懂的,我们一起来看一下。
这三个架构的区别在“M与V联系”的部分。针对这一部分我们来做一个对比:
Controller: 负责监听View的用户事件,得到数据后Controller做一些处理,然后渲染View。
当然,在一些后端MVC架构里,Model也可以直接渲染View模版,但这只是不同变种的实现,这里不多做讨论。 但是随时逻辑的复杂,这样的处理遇到了很难调试的问题。由于View一定要运行在UI环境下,而且Model或者Controller和View强耦合,没有办法单独验证应用逻辑的正确性。当出了问题之后,因为各个模块是耦合在一起的,也不能快速判断究竟是哪个模块出现的问题。因此,MVP模式出现了。
Presenter: 比起Controller,Presenter会调用View层提供的接口去渲染Model。这样做有几点好处:
现在P和V解耦了,P可以自己做单元测试了。软件结构划分的更加清楚,逻辑清晰并方便调试。但是这一切都来自于一个前提:View层要提供接口。当一个UI复杂起来的时候,View层需要提供的接口是很多的,这本身也是一种开发调试的成本。所以,MVVM应运而生。
ViewModel: 比起MVP中View需要自己提供API,MVVM在VM中构建一组状态数据(state data),作为View状态的抽象。然后通过双向数据绑定(data binding)使VM中的状态数据(state data)与View中的显示状态(screen state)保持一致。这样,VM中的展示逻辑只需要修改对应的状态数据,就可以控制View的状态,从而避免在View上开发大量的接口。
那么VM有没有什么缺点?有的,当UI比较简单的时候,使用VM就会使业务逻辑变得复杂,有过分设计的嫌疑。所以VM只适合复杂UI交互的项目。
举个例子:
我们的界面上原本没有任何东西,现在用户发出一个请求(点击按钮),界面上出现一张图片,或者一段文字。那么MVC、MVP、MVVM这三种架构都是如何处理的呢。
1. View获取用户请求,通知Controller。
2. Controller向后台Model发起请求
3. Model获得该请求所需要的数据,传递给Controller。
4. Controller拿到这些数据,可能做一些处理,然后拿处理好的数据渲染View。
MVC: 拿到UI节点,渲染这些数据
MVP: 通过View提供的接口渲染这些数据
MVVM: 无需操作,只要VM的数据变化,通过数据双向绑定,View直接随之变化。
这样是不是就很容易懂了。
最后我想提的是,MVC 的包容度比 MVVM 和 MVP 要来的高,在 MVC 的 V 层,可以再进一步的包含 MVVM 或 MVP 的实作,而 C 层也可以使用 MVP (V 是输出的资料) 来进一步切割数据的流动与输出,M 层则可以类似 MVVM 的架构,当 V (组件) 有数据的异动时,VM 即可自动侦测到并更新 Model (数据库)。当然,多大的脚就穿多大的鞋,要用什么样的架构去设计,要与当时的系统环境与需求来决定,而不是只想着要用同一种架构去做所有的系统。
学习这些概念的作用是培养我们的思考方式,站在巨人的肩膀上,了解他们的设计理念,搞清他们为什么要这样做,万一以后碰到了一些更为复杂的情况,用现有的这些无法解决时,我们就可以顺着这样的思路,自己去进行架构设计,解决问题。