为什么使用MVVM

iOS中,我们使用的大部分都是MVC架构。虽然MVC的层次明确,但是由于功能日益的增加、代码的维护,使得更多的代码被写在了Controller中,这样Controller就显得非常臃肿。

为了给Controller瘦身,后来又从MVC衍生出了一种新的架构模式MVVM架构。

MVVM分别指什么

MVVM就是在MVC的基础上分离出业务处理的逻辑到ViewModel层,即:

Model层:请求的原始数据

View层:视图展示,由ViewController来控制

ViewModel层:负责业务处理和数据转化

简单来说,就是API请求完数据,解析成Model,之后在ViewModel中转化成能够直接被视图层使用的数据,交付给前端(View层)。

MVVM与MVC的不同

首先我们简化一下MVC的架构模式图:

在这里,Controller需要做太多得事情,表示逻辑、业务逻辑,所以代码量非常的大。而MVVM:

MVVM的实现

比如我们有一个需求:一个页面,需要判断用户是否手动设置了用户名。如果设置了,正常显示用户名;如果没有设置,则显示“简书0122”这种格式。(虽然这些本应是服务器端判断的)

我们看看MVC和MVVM两种架构都是怎么实现这个需求的

MVC:

Model类:

#import

@interface User : NSObject

@property (nonatomic, copy) NSString *userName;

@property (nonatomic, assign) NSInteger userId;

- (instancetype)initWithUserName:(NSString *)userName userId:(NSInteger)userId;

@end

@implementation User

- (instancetype)initWithUserName:(NSString *)userName userId:(NSInteger)userId {

self = [super init];

if (!self) return nil;

_userName = userName;

_userId = userId;

return self;

}

@end

ViewController类:

#import "HomeViewController.h"

#import "User.h"

@interface HomeViewController ()

@property (nonatomic, strong) UILabel *lb_userName;

@property (nonatomic, strong) User *user;

@end

@implementation HomeViewController

- (void)viewDidLoad {

[super viewDidLoad];

//创建User实例并初始化

if (_user.userName.length > 0) {

_lb_userName.text = _user.userName;

} else {

_lb_userName.text = [NSString stringWithFormat:@"简书%ld", _user.userId];

}

}

@end

这里我们需要将表示逻辑也放在ViewController中。

MVVM:

Model类:

#import

@interface User : NSObject

@property (nonatomic, copy) NSString *userName;

@property (nonatomic, assign) NSInteger userId;

@end

ViewModel类:

声明:

#import

#import "User.h"

@interface UserViewModel : NSObject

@property (nonatomic, strong) User *user;

@property (nonatomic, copy) NSString *userName;

- (instancetype)initWithUserName:(NSString *)userName userId:(NSInteger)userId;

@end

实现:

#import "UserViewModel.h"

@implementation UserViewModel

- (instancetype)initWithUserName:(NSString *)userName userId:(NSInteger)userId {

self = [super init];

if (!self) return nil;

_user = [[User alloc] initWithUserName:userName userId:userId];

if (_user.userName.length > 0) {

_userName = _user.userName;

} else {

_userName = [NSString stringWithFormat:@"简书%ld", _user.userId];

}

return self;

}

@end

Controller类:

#import "HomeViewController.h"

#import "UserViewModel.h"

@interface HomeViewController ()

@property (nonatomic, strong) UILabel *lb_userName;

@property (nonatomic, strong) UserViewModel *userViewModel;

@end

@implementation HomeViewController

- (void)viewDidLoad {

[super viewDidLoad];

_userViewModel = [[UserViewModel alloc] initWithUserName:@"liu" userId:123456];

_lb_userName.text = _userViewModel.userName;

}

@end

可见,Controller中我们不需要再做多余的判断,那些表示逻辑我们已经移植到了ViewModel中,ViewController明显轻量了很多。说白了,就是把原来ViewController层的业务逻辑和页面逻辑等剥离出来放到ViewModel层。

总结:

MVVM同MVC一样,目的都是分离Model与View,但是它更好的将表示逻辑分离出来,减轻了Controller的负担;

ViewController中不要引入Model,引入了就难免会在Controller中对Model做处理;

对于很简单的界面使用MVVM会增加代码量,但如果界面中内容很多、Cell样式也很多的情况下使用MVVM可以很好地将VC中处理Cell相关的工作分离出来。

写到这里,MVVM基本上就算结束了。重要的还是去实践,在实践中检验真理。

MVVM的缺点

关于MVVM的缺点,Casa Taloyum大神在他的博客《iOS应用架构谈 网络层设计方案》中已经阐述的很详细了。这里简单的引用原文做一个回顾。

这种做法是能够提高后续操作代码的可读性的。在比较直觉的思路里面,是需要这部分转化过程的,但这部分转化过程的成本是很大的,主要成本在于:

数组内容的转化成本较高:数组里面每项都要转化成Item对象,如果Item对象中还有类似数组,就很头疼。

转化之后的数据在大部分情况是不能直接被展示的,为了能够被展示,还需要第二次转化。

只有在API返回的数据高度标准化时,这些对象原型(Item)的可复用程度才高,否则容易出现类型爆炸,提高维护成本。

调试时通过对象原型查看数据内容不如直接通过NSDictionary/NSArray直观。

同一API的数据被不同View展示时,难以控制数据转化的代码,它们有可能会散落在任何需要的地方。

针对这些缺点,Casa Taloyum大神也提出了相应的解决方法,即用一个类似reformer

的对象进行数据过滤,根据不同的reformer

对象过滤出不同的数据。这种方法,目前我也在进行尝试,之后我也会分享我的使用心得,敬请关注。

谢谢!

ios mvvm框架的封装_iOS MVVM架构总结相关推荐

  1. Silverlight实用窍门系列:52.Silverlight中的MVVM框架极速入门(以MVVM Light Toolkit为例)...

    在本文将以MVVM Light Toolkit为例讲解MVVM框架在现实中的使用入门,首先我们在http://mvvmlight.codeplex.com/下载它的MVVM框架下来.也可以通过 htt ...

  2. 案例挑战——MVVM框架理解和实践

    MVVM框架理解和实践 一.背景介绍 二. 什么是MVVM架构? 1.架构示意图 2.MVVM概念总结 3.实现VM的框架 三.通过案例来理解MVVM框架 1.没有使用MVVM架构的程序 2.使用了M ...

  3. 好程序员web前端分享MVVM框架Vue实现原理

    好程序员web前端分享MVVM框架Vue实现原理,Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js和react.js更加简洁 ...

  4. 深入聊聊MVVM框架(闲谈)

    深入聊聊MVVM框架(闲谈) MVVM 由以下三个内容组成: View :界⾯ Model :数据模型 ViewModel :作为桥梁负责沟通 View 和 Model 在 JQuery 时期,如果需 ...

  5. 面试题目之:mvvm框架是什么?它与其他框架(jquery)的区别是什么?哪些场景适合?

    面试题目之:mvvm框架是什么?它与其他框架(jquery)的区别是什么?哪些场景适合? (1)mvvm框架是什么? MVVM是Model-View-ViewModel的简写 Model:模型 Vie ...

  6. Android MVVM封装,MVVM: 这是一个android MVVM 框架,基于谷歌dataBinding技术实现

    MVVM 这是一个android MVVM 框架,基于谷歌dataBinding技术实现.dataBinding 实现的 V 和 VM的关联:使用IOC架构实现了 M 和 V的关联. 框架具有以下功能 ...

  7. Retrofit + Kotlin + MVVM 的网络请求框架的封装尝试

    1.前言 之前在学习郭霖<第一行代码>时按部就班地写过一个彩云天气 App,对里面的网络请求框架的封装印象非常深刻,很喜欢这种 Retrofit + Kotlin + 协程的搭配使用.随后 ...

  8. 《Android构建MVVM》系列(一) 之 MVVM架构快速入门

    前言 本文属于<Android构建MVVM>系列开篇,共六个篇章,详见目录树. 该系列文章旨在为Android的开发者入门MVVM架构,掌握其基本开发模式. 辅以讲解Android Arc ...

  9. “约见”面试官系列之常见面试题之第九十四篇之MVVM框架(建议收藏)

    目录 一句话总结:vm层(视图模型层)通过接口从后台m层(model层)请求数据,vm层继而和v(view层)实现数据的双向绑定. 1.我大前端应该不应该做复杂的数据处理的工作? 2.mvc和mvvm ...

最新文章

  1. java之泛型_java之泛型
  2. python程序一定要有主函数_Python 没有main函数的原因
  3. python3读取网页_python3+selenium获取页面加载的所有静态资源文件链接操作
  4. 百度地图infoWindow圆角处理
  5. spring aop设计模式_Spring框架中设计模式的运用
  6. 进击的美少女!浙大学姐两年发14篇论文! 一作10篇,顶刊4篇!
  7. 从文件夹里面多个文件里面查找指定内容
  8. 分布式架构下的“负载均衡”
  9. 洛谷3672:小清新签到题——题解
  10. 哈哈哈,看着问题一个个解决,很有满足感哦
  11. 【项目管理】 --- 范围说明书的内容和作用
  12. COGS2434 暗之链锁
  13. 大数据学习计划(不断改善)(小白入门指南)
  14. LINQ基础篇(中)
  15. 20个精美图表,教你玩转Pyecharts可视化
  16. 蓝牙BLE设备连接与通信
  17. 2022年美赛C题-交易策略-完整解题论文和代码
  18. API发送短信验证码
  19. 戴隐形眼镜好吗 隐形眼镜能经常戴吗
  20. 微信小程序关注公众号模板显示隐藏问题

热门文章

  1. 安卓蓝牙功能小结(附蓝牙聊天室demo)
  2. node进阶——之事无巨细手写koa源码(转)
  3. JavaScript网页小游戏:过河游戏
  4. Discuz搬家教程
  5. Gallery用法详解
  6. python获取文件后缀_Python使用filetype精确判断文件类型 (文件类型获取)
  7. linux分解psd文件,Autodesk SketchBook Pro PSD文件处理漏洞
  8. ebay API对接
  9. 【项目管理一点通】(2) 产品经理、项目经理、研发经理、技术经理、项目组长等
  10. 【BZOJ2400】Optimal Marks