iOS应用千万级架构:MVVM框架
业务模块内的MVC和MVVM架构
目前,唯品会中MVC和MVVM架构并存,后期会偏重于MVVM架构的使用。
MVC架构

Model:程序中要操纵的实际对象的抽象,为Controller提供经过抽象的业务数据,供Controller调度
View:视图,负责界面的元素的展示
Controller:控制器,管理View的声明周期及子view的生成和组装,负责Model和View之间的通信。
MVC框架的优势:
1. 应用广泛,几乎所有前端语言都有类似MVC的设计痕迹
2. 设计思想非常简洁,学习成本很低,新人上手非常容易。
MVC框架的问题:
MVC并没有对数据请求和处理逻辑代码应该放在哪一层做出明确地划分,因此一旦页面逻辑或交互稍微复杂,Controller就会变得很臃肿,代码也就越来越难维护。
MVVM架构

MVVM框架是在MVC的基础上演化而来,MVVM想要解决的问题是尽可能地减少Controller的任务。
Model:程序中要操纵的实际对象的抽象
View(ViewController):MVVM中的View不再是UIView的子类,而变成了UIViewController的子类。这里的View实际上就是MVC中剥离了处理呈现View逻辑部分的Controller,因此它仍然有各种UIView的属性,仍然有ViewController的声明周期的各种方法,但是这里的Controller不再负责数据的请求以及处理逻辑,因此不再臃肿。
ViewModel:MVVM中,ViewModel代替了MVC中的Controller成为了协调者的角色,ViewModel被View(ViewController)持有,同时持有者Model。数据请求以及处理逻辑都放在ViewModel中,View(ViewController)就瘦了下来。
MVVM框架的优势:
1. View(ViewController)通过对ViewModel中的数据进行绑定来更新界面,不用通过逻辑或者条件判断来更新view,大大降低了复杂交互时出bug的几率。
2. View(ViewController)中代码简洁,后期的维护和优化比较容易。
MVVM框架的问题:
学习成本比MVC高,如果对MVVM的职责划分理解不透彻,很容易导致ViewModel的存在形同虚设, 反而增加了维护的成本。
我们为什么要用MVVM?
订单售后这个页面内容非常多,而且里面的内容会变,还可以收缩展开,还会出现由接口请求成功或失败来控制某一部分的显示还是隐藏。当你使用普通的MVC架构的时候,你会发现,在controller里的代码量非常惊人的,View的计算也非常复杂,当有一块内容要在中间展示的时候,下面的所有的View的Y值都得重新计算。显然,维护成本是非常高的,改动一个小点还可能会导致蝴蝶效应,测试也要回归当前页面所有的用例。
那有没有好的办法来解决这些问题呢?我只想在自己的小块里加功能,当小块的内容高度变化了,整个页面的布局高度跟着自己变化呢。答案是有的,那就是使用MVVM模式。
看下图的UML类图,分析一下,如下:

下面就CollectionView做说明,每一个内容都是一个小块Cell,都有自己的cellViewmodel,整个控制器有一个大的viewmodel,包装所有的cellViewmodel,就这样构建一个页面。
1、itemCell 是小块Cell,里面主要是初始化View,更新View的数据,需要返回cell的宽高
2、cellViewModel,是itemCell的ViewModel,给itemCell 提供数据,itemCell的点击事件也是回调到cellViewModel中。
3、Cell1ViewModel 和 item1Cell 组成一个小块Cell1
4、Cell2ViewModel 和 item2Cell 组成另一个小块Cell2
5、ViewModel 网络请求拿到数据之后,组装上面的小块Cell1ViewModel、小块Cell2ViewModel,通过方法【 - (Class)cellClass 】就可以拿到当前的itemCell
6、ViewModel中,还通过block的方式,对Controller回调绑定了事件,比如cell的点击事件、加载数据成功事件、按钮点击事件等
例子
Demo有两种处理方式,一是通过继承基类,重写基类的方法来实现;二是通过协议,cell使用cellprotocol协议,cellModel使用cellModelProtocol协议。
使用方法
直接继承MVVMBase使用
- 新建一个控制器VSDemoCollectionViewController,继承于VSMVVMCollectionViewController
- 新建一个该控制器的ViewModel(VSDemoCollectionViewModel),继承于VSMVVMCollectionViewModel,负责管理所有的CellViewModel
- 新建一个CellModel(VSDemoCollectionItemCellModel),继承于VSMVVMCollectionViewCellModel,负责管理元素Cell,在方法cellClass中,返回关联的Cell(VSDemoCollectionItemCell)
- 新建一个Cell(VSDemoCollectionItemCell),继承于VSMVVMCollectionViewCell,需要重写VSMVVMCollectionViewCell中的方法,返回该cell的高度。
- 页面很复杂,需要重新步骤3和4,不断的拆分这个复杂的Cell.
- 最后,所有的cellModel都交由第2步的控制器的ViewModel整合加载。
代码Demo已经上传到github: https://github.com/jiangys/VSMVVM
iOS应用千万级架构:MVVM框架的更多相关文章
- iOS应用千万级架构开篇
一款好的APP架构,是需要适应复杂的业务场景的.当然它也是可以监控的,比如性能.卡顿等.你写的每一行代码,测试都可以查看到,并测试覆盖到. 一直很想分享一下,一个大型的APP都做了些什么事情,这些事情 ...
- iOS应用千万级架构:性能优化与卡顿监控
CPU和GPU 在屏幕成像的过程中,CPU和GPU起着至关重要的作用 CPU(Central Processing Unit,中央处理器) 对象的创建和销毁.对象属性的调整.布局计算.文本的计算和排版 ...
- 移动架构-MVVM框架
MVVM是Model-View-ViewModel的简写.它本质上就是MVC 的改进版.MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开 MVVM的优点 可重用性 ...
- Erlang千万级用户游戏框架(Openpoker)源码文件分析清单
openpoker源码 erlang写的网游服务器源码,OpenPoker是一个大型多人扑克网游,内建支持了容错能力,负载平衡和无限制的规模大小.本文是openpoker源码文件功能的一个清单式说明: ...
- iOS开发之浅谈MVVM的架构设计与团队协作
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- 浅谈千万级PV/IP规模高性能高并发网站架构(转自老男孩)
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://oldboy.blog.51cto.com/2561410/736710 如果把来 ...
- 浅谈千万级PV/IP规模高性能高并发网站架构
高并发访问的核心原则其实就一句话“把所有的用户访问请求都尽量往前推”. 如果把来访用户比作来犯的"敌人",我们一定要把他们挡在800里地以外,即不能让他们的请求一下打到我们的指挥部 ...
- (转)浅谈千万级PV/IP规模高性能高并发网站架构
浅谈千万级PV/IP规模高性能高并发网站架构 原文:http://blog.51cto.com/oldboy/736710 文章架构简图: 高并发访问的核心原则其实就一句话“把所有的用户访问请求都 ...
- Mysql limit 优化,百万至千万级快速分页,--复合索引的引用并应用于轻量级框架
MySql 性能到底能有多高?用了php半年多,真正如此深入的去思考这个问题还是从前天开始.有过痛苦有过绝望,到现在充满信心!MySql 这个数据库绝对是适合dba级的高手去玩的,一般做一点1万篇新闻 ...
随机推荐
- 8000字长文让你彻底了解 Java 8 的 Lambda、函数式接口、Stream 用法和原理
我是风筝,公众号「古时的风筝」.一个兼具深度与广度的程序员鼓励师,一个本打算写诗却写起了代码的田园码农! 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在 ...
- SpringMVC+Mybatis初尝试
一个月前简单学完了SpringMVC框架和Mybatis框架,一直没有使用过,今天主要用它做了个简单的学生管理系统,不过第一次用框架,实现的功能简单,比较low. 注:这里使用的数据库是SQLServ ...
- .Net Core微服务入门全纪录(二)——Consul-服务注册与发现(上)
前言 上一篇[.Net Core微服务入门全纪录(一)--项目搭建]讲到要做到服务的灵活伸缩,那么需要有一种机制来实现它,这个机制就是服务注册与发现.当然这也并不是必要的,如果你的服务实例很少,并且很 ...
- CSS文本相关之水平排列[4]
在正常流中,文本都是从左往右.自上而下排列显示,如果想要改变排列方向的话,可以通过CSS属性来改变. text-align属性 文本排列(text-align)可改变文本在水平上的方向,但不改变内部的 ...
- numpy矩阵相加时需注意的一个点
今天在进行numpy矩阵相加的时候出现了一个小的奇怪的地方,下面我们来看看: >>>P = np.array([1,2,3,4]) >>>F = np.array( ...
- Android学习笔记BroadcastReceiver(广播接收者)
Android发送广播的过程 代码实现 MainActivity.java import androidx.appcompat.app.AppCompatActivity; import androi ...
- ca33a_demo_c++_新旧代码的兼容char数组与vector_string相互转换
/*ca33a_demo_c++33_CppPrimer_新旧代码的兼容_txwtech旧代码:数组和c风格字符串新代码:vector和string相互转换:c风格字符串<- ->stri ...
- Java 多线程基础(七)线程休眠 sleep
Java 多线程基础(七)线程休眠 sleep 一.线程休眠 sleep sleep() 方法定义在Thread.java中,是 static 修饰的静态方法.sleep() 的作用是让当前线程休眠, ...
- Day8-微信小程序实战-交友小程序-首页用户列表渲染及多账号调试及其点赞功能的实现
在这之前已经把编辑个人的所有信息的功能已经完成了 之后先对首页的列表搞动态的,之前都是写死的静态 1.之前都是把好友写死的,现在就在js里面定义一个数组,用循环来动态的绑定 在onReady中定义,取 ...
- 【Java】HashMap实现原理---数据结构
作为一个程序猿,特别是Java后端的,应该全部人都用过HashMap,也都知道HaspMap是一个用于存储Key-Value键值对的集合.与此同时我们把每一个键值对也叫做 Entry. 而这些Entr ...