iOS架构设计(三)- MVVM

我是不敢轻易谈MVVM架构设计的

终于在经过前面几篇文章内容的铺垫之后,现在简单说说自己的想法

切记,如果没有kvc kvo的原理知识铺垫,最好去复习一下,否则看过了解,回头就会忘却,不会形成意识

  • KVC原理

  • KVO原理

  • iOS架构设计(一)- MVC

  • iOS架构设计(二)- MVP

再次提醒:务必去了解一下 kvc kvo原理

因为我在文中MVVM的架构设计会依赖自定义KVO机制去实现

MVVM也会基于之前的 iOS架构设计(二)- MVP 去实现,所以没有看过的同学建议还是先出门阅读下

MVVM的本质

首先 架构设计更新到MVVM,是在MVC MVP KVC KVO的基础上发展而来的,我计划用前面的内容来成就MVVM,而不会增加新的内容,更不会平白无故的增加额外的管理类什么的

否则 前面几章铺陈就变得毫无意义可言 那这篇文章就如同行尸走肉一般 而我就是全身腐化气质了,我并不想那样

可能人各有偏好,我不理解的是 我看过一些别人写的MVVM,个人觉得没有特别适合我的,不知道是block炫技 还是秀delegate,思想我是get到了,可代码凌乱不堪,我考虑的是 我用这样的设计,怎么跟别人协作项目,我心里是没信息

争取我在此篇文章里阐述的能使我自己不迷糊,如能触碰到你心里的点,这篇文章的价值才出得来

先看一张图

image.png

这是我看到的一个利用MVVM的项目,我整理了下设计流程

图中的意思我简单概括下

  • 一个vc创造一个manager,manager呢功能很强,因为遵从3个协议,也就是把控制权交给了manager,但是这样的操作跟VC本身做又有什么区别

  • manager通过viewModel作为delegate 调度viewModel去管理view

  • viewModel又通过 manager遵从协议 驱动一些其他类,而且还是关联对象存储

  • viewMode又通过数据更新渲染view

  • 。。。。。

反正 我看到毛毛多的block,block泛滥,不是排斥,只是这种block爆发蔓延,看上去挺高大上,反正很快要抓住主干思想脉络 我是做不到的

我按照这样的架构设计去安排我的代码,图中的很多线我都需要考虑,不得不考虑,环节对不上,我的视图可能就刷新不起来;

而且很多关系是靠代码逻辑演化出来的,也就是我没办法从顶层设计上确切知道我未来的代码走势,复杂度会演化成什么样子,我都不知道

我自己没那个信心 能践行得很好,从项目角度上讲,我自己在这个架构设计下,是没有把控能力的

总之 我觉得是很乱,如果让我选,我毫不犹豫选择我之前设计的那个MVC,比这个好用,功能也不弱,协作起来问题也不大

回到正题

回到从MVVM最本质的思想

image.png

这张图的意思很明了,就两根线

  • 一根 View <-> viewModel

  • 一根 viewModel <-> Model

如果这篇文章里我们能解决这两根线,基本上就算实现了MVVM

除此之外,为了达到这个目的,我们的其他嫁接配置部分代码不应该侵入这两条线

这个思想很纯粹,很精辟 (ViewModel可以理解为一个大圣人,无所不能)

  • 视图通过 ViewModel来渲染 不管是主动的还是被动的,反正就一条线;

  • 视图的交互状态提交给 ViewModel;

  • Model通过ViewModel来交付;

  • Model本身的增删改 同步给ViewModel

接下来 我会按照上面的两条线的解读来设计

MVP的底子

image.png

会不会有人有疑问呀,这是骗人的吧?????

那么多代码,就这几条线,糊弄的吧。。。。

我相信会有人在心里这样犯嘀咕

因为很多工作包括配置是在基类初始化中完成的,所以我画了两条虚线,VC构建了两个重要的角色,View和Presenter

而这些基类跟配置属于万年不变的类,它的配置调试只属于架构者,项目定式后,可以选择作为库,项目中的其他成员是不涉及的,剩下的工作就是依赖那两条实线了

那对比一下上面MVVM的那个思想图

  • 我把最右侧的那条弯弯虚线变成实线

  • 给View添加观察者Adapter,

  • 给 Adapter添加观察者 Presenter,

这样就变成两条 双向的线,

而且我把Adapter换成一个神奇名字 -- ViewModel

Presenter可以换成 Model,不过从职能上来将,我还是觉得Presenter更合适

我就基本上把之前的MVP改造成了一个MVVM架构,

更确切的说,是 PVVM, P就是Presenter

这可能么,我倒不存什么疑问,最起码我是按照MVVM的设计思想来调整的我的MVP,不觉得有什么冲突的地方

从MVP处拷贝一份代码出来

image.png
image.png

首先这份mvp架构设计的代码是没问题的,只是我把关键字 list 替换成了 list1
接下来就是我们魔改了

adapter我打算沿用,名字不做更改,主要还是为了方便对比 MVP

给图方便描述修改过程,我把MVP原理图上的线给编上号

image.png

MVP调整过程

去掉线3

image.png

分两步

image.png

image.png

presenter驱动view刷新 变成了 adapter的责任

image.png

现在代码 按照图中 线的变化 调整,去掉线3,增加线6

由于线3去掉了,则View的渲染驱动就没有了,此消彼长,在别处也就是adapter补上

image.png
image.png
image.png

你会发现在adapter中 一句关键代码 [self needRefresh] View刷新渲染数据

目的是达到了,有点粗糙

可以先看下原因

image.png

其实就是View作为adapter的观察者,被动刷新渲染

image.png

MVP的架构设计只改了一点点,目前列表数据加载都是正常,加减操作 逻辑没有受任何影响

添加View -> Adapter 的一条实线

线5我画的是虚线,所以不用管它

image.png

不用改代码,线自然就补充上来了,就相当于 View触发 执行了一个同步流程,View也就拿到了返回值,刷新

这条线的添加就不用改代码了

顺便 Adapter -〉 Presenter 那条线也就有了

由此,MVVM也就改好了,我更习惯称之为 VAP, 也就是 View - Adapter - Presenter

Adapter 就是ViewModel Presenter就是Model

这种设计就是个双向的管道, 一头是View,一头是Presenter

Presenter是数据的源头,自然而然从Presenter流入View,期间经过Adapter

View最终是要把数据渲染到视图上去的,状态的变化自然要回溯到源头Presenter,中间也经过Adapter

比预想到修改要少好多好多,因为MVP中有一个context的设计,所以目前这种架构设计还可以再调整,
得益于灵活的context设计

你会否觉得与你预想的不一样,感觉文章就没说头,反正对我而言,设计就这些,更复杂的代码在此基础上 不会变得烦乱不可控,有凌乱的也只会是在局部,不会在整个设计中蔓延开来

我平时就是这样来控制的,不是说细节做到尽善尽美,也有瑕疵的地方,但不影响大局

还有一部分没拿出来说明,就是这个设计架构本身有些业务代码是来自工程编译本身产生的,

那是因为在这个设计里设定了一些规则,一些职能类的命名规范,还有功能流转方式是可以被这个架构设计严格限制的

这样即便项目庞杂了,想堆代码是不可行的,堆代码只会影响自己的业务本身,不安规矩来的话,就会发现代码根本是跑不通的

进一步抽象 改名

代码改到这个地步,感觉根一般见到的MVVM一点都不像,没关系,我们继续

抽象出一个baseview

image.png
  • 把订阅放到VC的配置阶段
image.png
  • View中去掉订阅逻辑,通用的订阅逻辑交由base
image.png

如此,View 与 ViewModel之间就从代码层面上看出订阅关系了

View与ViewModule的业务绑定

image.png

同样 这些也是base处理的,View本身透明

image.png

View订阅之后,剩下的就是

  • 数据的整体刷新到来,响应刷新

  • 根据订阅的自定义类型,局部处理

这里不选用block,是因为用block会在View里多了一些不必要的配置,不够纯粹,当前的方式 只需要处理这两个方法就可以了,而且换个模块 方法名也是固定的,基本上View里的代码个是就是固定的模板了

涉及的代码部分,同样可以从 github 获取

你可能感兴趣的:(iOS架构设计(三)- MVVM)