• 主页
  • 随笔
  • 技术笔记
  • 全部文章
标签 友链 关于我

  • 主页
  • 随笔
  • 技术笔记
  • 全部文章

浅谈MVC,MVP,MVVM及VIPER架构

阅读数:次 2020-06-02
字数统计: 2.8k字   |   阅读时长≈ 9分
  • 所谓架构二字,核心即是对于客户端的代码组织/职责划分。
  • 本质上都是三个角色:数据管理者、数据加工者、数据展示者。
  • 无非是把数据管理者的工作进行拆分、唯一的界定标准就是把工作拆分的粒度大小。
  • 而无论哪种思想、最终都逃不开三个问题的取舍。代码量、通用性、可读性。

前言

现在我们面对架构设计模式的时候有了很多选择:
- MVC
- MVP
- MVVM
- VIPER

首先前三种模式都是把所有的实体归类到了下面三种分类中的一种:

- Models(模型)数据层,或者负责处理数据的 数据接口层。
- Views(视图) - 展示层(GUI)。对于 iOS理论上来来说所有以 UI 开头的类基本都属于这层。
- Controller/Presenter/ViewModel(控制器/展示器/视图模型)
  它是 Model 和 View 之间的胶水或者说是中间人。
  一般来说,当用户对 View 有操作时它负责去修改相应 Model;当 Model 的值发生变化时它负责去更新对应 View。

一、MVC“架构”

经典MVC模式在提出时,更贴近现时代得说,在这种架构下,View 是无状态的,
在Model变化的时候它只是简单的被 Controller重绘,
尽管这种架构可以在应用里面实现,但是由于 MVC 的三种实体被紧密耦合着,每一种实体都和其他两种有着联系,
所以即便是实现了也没有什么意义。

View 和 Model 之间是相互独立的,它们只通过 Controller 来相互联系。这样的设计,使得View 和 Model 直接解耦合了。  
但是现实中我们的View依然跟Model耦合,因为如果完全按照这个理想化的MVC的话,View(cell)层的设置都应该在 Controller中,这样的话,Controller会更臃肿。

Cocoa MVC 鼓励你去写重控制器是因为 View 的整个生命周期都需要它去管理,
Controller 和 View 很难做到相互独立。虽然你可以把控制器里的一些业务逻辑和数据转换的工作交给 Model,
但是你再想把负担往 View 里面分摊的时候就没办法了;
因为 View 的主要职责就只是讲用户的操作行为交给 Controller 去处理而已。
于是 ViewController 最终就变成了所有东西的代理和数据源,甚至还负责网络请求的发起和取消。最后变得臃肿不堪。
另一方面UIViewController负责了界面跳转的操作,界面跳转的相关配置是直接在对应的UIViewController实例上设置的,这样就很容易把源界面和目的界面耦合起来,表现在导入很多其他头文件。

二、MVP“架构”

MVC的缺点在于并没有区分`业务逻辑和业务展示`, 这对单元测试很不友好. MVP针对以上缺点做了优化, 
它将业务逻辑和业务展示也做了一层隔离, 对应的就变成了MVCP. 
M和V功能不变, 原来的C现在只负责布局, 而所有的业务逻辑全都转移到了P层。
P层处理完了业务逻辑,如果要更改view的显示,那么可以通过回调来实现,这样可以减轻耦合,同时可以单独测试P层的业务逻辑。

在 MVP 中,Presenter 可以理解为松散的控制器,其中包含了视图的 UI 业务逻辑,
所有从视图发出的事件,都会通过代理给 Presenter 进行处理;
同时,Presenter 也通过视图暴露的接口与其进行通信。`而这一般是在 Controller中处理的。`
  • View负责界面展示和布局管理,向Presenter暴露视图更新和数据获取的接口
  • Presenter负责接收来自View的事件,通过View提供的接口更新视图,并管理Model
  • Model和MVC中的一样,提供数据模型
与MVC区别就是IOS中:
 (1)苹果的理想MVC中UIView相当于View,UIController是Controller,而在MVP中,UIView和UIController都相当于View,所以在 Presenter 里面基本没什么布局相关的代码,它的职责只是通过数据和状态更新 View。
 (2)持有关系也不一样,MVC中 C 持有 M和V,但是在MVP中 V 持有 P,P 持有M 。
 (3)在 MVP 架构里面,UIViewController 的那些子类其实是属于 View 的,而不是 Presenter。这种区别提供了极好的可测性,但是这是用开发速度的代价换来的,因为你必须要手动的去创建数据和绑定事件

MVC和MVP的关系

我们都知道MVP是从经典的模式MVC演变而来,它们的基本思想有相通的地方:
Controller/Presenter负责逻辑的处理,Model提供数 据,View负责显示。作为一种新的模式,
MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,
它们之间的通信是通过 Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,
而在现实中的MVC中View会直接从Model中读取数据而不是通过 Controller。

MVP优缺点:

  • UI布局和数据逻辑代码划分界限更明确。
  • 理解难度尚可,较容易推广。
  • 解决了Controller的臃肿问题。
  • Presenter-Model层可以进行单元测试。
  • 需要额外写大量接口定义和逻辑代码(或者自己实现KVO监视)。

三、MVVM“架构”

iOS 里面的 ViewModel 到底是个什么东西呢?本质上来讲,他是独立于 UIKit 的, 
View 和 View 的状态的一个呈现(representation)。ViewModel 能主动调用对 Model 做更改,
也能在 Model 更新的时候对自身进行调整,然后通过 View 和 ViewModel 之间的绑定,对 View 也进行对应的更新。
MVVM:一个 MVC 的增强版,
我们正式连接了视图和控制器,并将表示逻辑从 Controller 移出放到一个新的对象里,即 View Model。MVVM 听起来很复杂,但它本质上就是一个精心优化的 MVC 架构。

MVVM vs MVP区别:

首先ViewModel-Model层和之前的Present-Model层一样,没有什么大的变化。View持有ViewModel,这个和MVP也一样。变化主要在两个方面:
1.ViewModel相较于Present,不仅仅是个逻辑处理机,它附带了自己的状态,所以被才可以被称为“Model”。
ViewModel也因为这个变的更加独立完整,我们更容易通过ViewModel的状态去进行单元测试。
Presenter在没有设置回调的时候其实一直在做空运算而已,运算得到的值没有进行存储,下次必须重新运算。
2.View不直接通过传递用户操作来控制ViewModel,ViewModel也不直接通过回调来修改View。对常用的数据和UI控件的事件&属性,MVVM框架的底层均进行了封装,使得我们可以进行数据绑定操作。
简单来说我们可以用类似[viewModel.username bind:usernameTextField.text]类似的操作使得viewModel的属性和UI控件的属性相互绑定,其中一方修改的时候另一方直接自动做对应更改。
这样的话我们就不用重复的书写很多回调操作,也不用处理一大堆UI控件的delegate事件。
MVVM模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。
唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。
这样开发者就不用处理接收事件和View更新的工作,框架已经帮你做好了。

其实MVVM的精华小部分在ViewModel,更大部分就在数据绑定,甚至有很多人觉得应该称MVVM为MVB(Model-View-Binder)。主要结合RAC使用,否则跟MVP无太大区别。

四、VIPER“架构”

到目前为止,你可能觉得我们把职责划分成三层,这个颗粒度已经很不错了。
现在 VIPER 从另一个角度对职责进行了划分,这次划分了五层。

VIPER并不复杂,它是将原来MVC中的Controller中的各种任务进行了清晰的分解,在写代码时,你会很清楚你正在做什么。
事实上,它比使用了数据绑定技术的MVVM更加简单,就是因为它职责明确。从MVC转到VIPER的过程同样是很清晰的,
它甚至把重构的思路都体现出来了。而MVVM则留下了许多尚未明确的责任,导致不同的人会在某些地方有不同的实现。

*  View
         提供完整的视图,负责视图的组合、布局、更新
         向Presenter提供更新视图的接口
         将View相关的事件发送给Presenter
*   Interactor(交互器) 
          维护主要的业务逻辑功能,向Presenter提供现有的业务用例
          维护、获取、更新Entity
          当有业务相关的事件发生时,处理事件,并通知Presenter
*   Presenter(展示器) 
          接收并处理来自View的事件
          向Interactor请求调用业务逻辑
          向Interactor提供View中的数据
          接收并处理来自Interactor的数据回调事件
          通知View进行更新操作
          通过Router跳转到其他View
*   Entities(实体) 
          纯粹的数据对象。不包括数据访问层,因为这是 Interactor 的职责。
*   Router(路由)
          负责 VIPER 模块之间的转场
          提供View之间的跳转功能,减少了模块间的耦合
          初始化VIPER的各个模块

和其他模式的区别

VIPER把MVC中的Controller进一步拆分成了Presenter、Router和Interactor。
和MVP中负责业务逻辑的Presenter不同,VIPER的Presenter的主要工作是在View和Interactor之间传递事件,
并管理一些View的展示逻辑,主要的业务逻辑实现代码都放在了Interactor里。
Interactor的设计里提出了”用例”的概念,也就是把每一个会出现的业务流程封装好,这样可测试性会大大提高。
而Router则进一步解决了不同模块之间的耦合。

优点

VIPER的特色就是`职责明确,粒度细,隔离关系明确`,这样能带来很多优点:
  *   可测试性好。UI测试和业务逻辑测试可以各自单独进行。
  *   易于迭代。各部分遵循单一职责,可以很明确地知道新的代码应该放在哪里。
  *   隔离程度高,耦合程度低。一个模块的代码不容易影响到另一个模块。
  *   易于团队合作。各部分分工明确,团队合作时易于统一代码风格,可以快速接手别人的代码。

缺点

*   一个模块内的类数量增大,代码量增大,在层与层之间需要花更多时间设计接口。
*   模块的初始化较为复杂,打开一个新的界面需要生成View、Presenter、Interactor,并且设置互相之间的依赖关系。
  • 本文作者: Grx
  • 本文链接: https://ruixiaoguo.github.io/Grx.github.io/Grx.github.io/2020/06/02/浅谈MVC,MVP,MVVM及VIPER架构/
  • 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!
  • OC

扫一扫,分享到微信

IOS RAC基本使用
iOS苹果审核之路
  1. 1. 前言
  2. 2. 一、MVC“架构”
    1. 2.0.0.1. 于是 ViewController 最终就变成了所有东西的代理和数据源,甚至还负责网络请求的发起和取消。最后变得臃肿不堪。
    2. 2.0.0.2. 另一方面UIViewController负责了界面跳转的操作,界面跳转的相关配置是直接在对应的UIViewController实例上设置的,这样就很容易把源界面和目的界面耦合起来,表现在导入很多其他头文件。
  • 3. 二、MVP“架构”
    1. 3.0.0.1. 与MVC区别就是IOS中:
  • 3.1. MVC和MVP的关系
  • 3.2. MVP优缺点:
  • 4. 三、MVVM“架构”
    1. 4.0.0.1. MVVM:一个 MVC 的增强版,
    2. 4.0.0.2. 我们正式连接了视图和控制器,并将表示逻辑从 Controller 移出放到一个新的对象里,即 View Model。MVVM 听起来很复杂,但它本质上就是一个精心优化的 MVC 架构。
  • 4.1. MVVM vs MVP区别:
    1. 4.1.0.1. 首先ViewModel-Model层和之前的Present-Model层一样,没有什么大的变化。View持有ViewModel,这个和MVP也一样。变化主要在两个方面:
    2. 4.1.0.2. 1.ViewModel相较于Present,不仅仅是个逻辑处理机,它附带了自己的状态,所以被才可以被称为“Model”。 ViewModel也因为这个变的更加独立完整,我们更容易通过ViewModel的状态去进行单元测试。 Presenter在没有设置回调的时候其实一直在做空运算而已,运算得到的值没有进行存储,下次必须重新运算。
    3. 4.1.0.3. 2.View不直接通过传递用户操作来控制ViewModel,ViewModel也不直接通过回调来修改View。对常用的数据和UI控件的事件&属性,MVVM框架的底层均进行了封装,使得我们可以进行数据绑定操作。 简单来说我们可以用类似[viewModel.username bind:usernameTextField.text]类似的操作使得viewModel的属性和UI控件的属性相互绑定,其中一方修改的时候另一方直接自动做对应更改。 这样的话我们就不用重复的书写很多回调操作,也不用处理一大堆UI控件的delegate事件。
  • 4.1.1. 其实MVVM的精华小部分在ViewModel,更大部分就在数据绑定,甚至有很多人觉得应该称MVVM为MVB(Model-View-Binder)。主要结合RAC使用,否则跟MVP无太大区别。
  • 5. 四、VIPER“架构”
    1. 5.0.1. 和其他模式的区别
  • 5.1. 优点
  • 5.2. 缺点
  • © 2014-2024 Grx
    GitHub:hexo-theme-yilia-plus by Litten
    本站总访问量次 | 本站访客数人
    • 标签
    • 友链
    • 关于我

    tag:

    • life
    • OC
    • Google
    • Fastlane
    • Flutter
    • hexo
    • 智能家居
    • Apple Watch
    • 逆向
    • Lottie
    • PHP
    • cocos2d
    • Mac
    • MonkeyKing
    • RN
    • Swift
    • RAC
    • WKWebView
    • WebView
    • Xcode
    • xcode
    • ios
    • Android
    • appledoc
    • MMKV
    • LLVM
    • FreamWork






      
      

    • 唐巧的博客
    • 王巍(喵神)OneVsDen
    • 阿里“念纪“
    • 滴滴-戴铭
    • 郭曜源(ibireme)
    • 阿里”南栀倾寒“
    • 蘑菇街李忠
    • 码农人生
    • 玉令天下
    • bang
    • Ian的博客
    这里是Grx的个人博客:
    iOS开发工程师一枚
    联系方式:
    QQ:1217255509
    Email:grx0917@sina.com
    知识管理,时间管理,自我管理,架构即未来
    欢迎技术交流!