浅谈iOS架构(结合公司项目)

项目背景:

在移动互联网行业,公司算得上是一个元老了,赶上了第一波移动互联网创业的热潮,于是公司的APP项目也在那个时候应运而生,但是任何事物都有两面性,有时候早也并不是好事,仅仅对于我们iOS的工程来说就是这样。听前辈们讲,我们APP大概经历了四代人开发,大概划分一下如下:

  • 第一代:在那时候,会写一个网络请求,会一个tableview,你就可以在这个领域站得住脚,所以第一版本没有任何设计而言,只是需要实现功能
  • 第二代:在iOS项目开发中,MVC是苹果力推的架构模式。经过了一定时间积累和沉淀,公司项目逐渐往这个方向发展,渐渐有了一些清晰的结构
  • 第三代:随着公司的发展,业务的扩大,APP的功能越来越多,越来越复杂。这时候APP整个项目结构开始变得臃肿混乱,但不敢轻易重构
  • 第四代:我们现在这一波人,在重构的道路上,全力填前人留下的坑

APP架构大概演进路线:

MRC → ARC,MVC → 分层设计, MVVM,组件化

我进公司的时候,现在的team leader正在对整个APP进行重构,据他说整个APP已经没法继续开发下去了,结构混乱不堪。由于前面工程使用的MRC,而且当时工程师的开发水平参差不齐,造成项目线上崩溃率很高。team leader带着一批人,首先把整个项目转变成ARC,换掉一些老的框架,自己重写。然后项目被划分为逻辑底层,业务层,UI层。UI层调用业务层,业务层调用逻辑层,不允许三层之间相互调用,这样一个整个软件架构已经解决了大部分的耦合了,对于后面进来的同事可以很快了解熟悉APP,对于后续持续化开发有了质的提升

目前APP结构:

  • 逻辑层:HTTP框架,TCP框架,数据库框架等(稳定,不会随APP业务变化的内容)

  • 业务层:适应公司自有业务,如会员,资料,分享等的管理(适应公司业务,随时增加或者修改)

  • UI层:这里说UI层是简称,说的就是APP开发的一层,下面也具体谈谈这一层,到了这一层我们才会谈到MVC,MVVM或者是其他的一些架构。我们APP之前在这一层使用的是传统MVC开发,对大多数人来说,MVC非常熟悉亲切,这也是Apple对于iOS开发推荐的架构模式

MVC与MVVM:

MVC

我们所熟知的MVC其实Apple给我们提供的Cocoa MVC,Apple提倡的MVC中,view和model是相互独立的,只通过controller来进行交互

  • Model进行数据管理
  • View根据数据进行视图渲染
  • Controller对Model以及View进行调配

但是这里存在一个问题,由于controller中本身存在一个view,所以很难做到view和controller完全独立,因此controller要管理view的生命周期和响应一些界面操作虽然model可以分担一些简单数据处理,但是最终还是会发现controller变成了所有东西的代理和数据源。一旦业务相对复杂一点,controller代码量会非常大,而且随着业务的增加,代码量会持续增加,而model和view却相对稳定,这对于以后的维护是灾难性的。(我们的APP中当时存在数个代码5000行以上的控制器,重构时的痛苦自不必多说)

有一点值得思考,我们都应该遇到过这样的场景,tableview里给cell填充数据的时候调用的方法大概是这样

- (Void)setData:(XXXModel)model

这里大家有没有注意到,cell里面是有model的,所以这里是不是已经违背了MVC的原则了呢,但是这种情况确实是一直在我们开发的过程中发生,我们也没感觉到哪里奇怪。如果严格遵守MVC的话,你会把对cell的设置放在controller中,不向view传递一个model对象,如果cell的样式过多,这样controller的体积是不可想象的。所以其实我们在开发过程中已经不知不觉的在修改MVC这种架构了,因为它确实是存在弊端的。

总结一下MVC:

  • 优点:在项目初期,MVC的确可以快速的构建一个APP,并且结构清晰,对于程序员来说更容易理解,上手开发很快,阅读起来容易
  • 缺点:随着公司的业务增加,APP更为健壮的时候,MVC就显得不堪重负,维护成本显著增加,对业务的增删改简直是灾难,一个动作会牵一发而动全身

如何才是一个正确姿势的MVC呢,我理解的如下:

  • model:给controller提供数据相关的接口,可以提供轻量级的业务接口
  • controller:管理view的什么周期,监听界面操作,调度model和view
  • view:只用来刷新界面,如展示动画,展示界面元素等

MVVM

MVVM从前两三年开始在iOS开发中讨论度非常高,现在已经是一种非常成熟的思想了。其初衷也是为了controller减负,把数据业务处理的部分从controller中移出去

  • model:和MVC一样,基本的数据单元
  • view:也和MVC差不多,不接受逻辑,只做视图展示
  • viewmodel:处理数据,业务逻辑

这里有几个重要的地方:

  1. 首先可以看到controller哪里去了,其实这里view和controller可以划归为一层,controller只是接收view的事件,也就是用户操作界面,然后将事件传递给viewmodel处理。controller在这里扮演的只是一个中间人的角色
  2. viewmodel不要包含任何view相关的东西,viewmodel之间可以有相互依赖,但是要尽量避免,否则重蹈controller的覆辙,变得难以维护

很多人提到MVVM就提到了Reactive,实际上两者完全没有任何联系,MVVM是一种软件架构,而Reactive是一种编程思想,我们所说的ReactiveCocoa或者RxSwift是用这种思想编写的一个框架,目的在于让我们更容易实现这种编程模式。也就是说不用这两个框架,一样可以实现MVVM。那么到底如何实现一个MVVM呢,其实很简单:

只要在MVC的基础上,把Controller拆出一个ViewModel专门负责数据处理的事情,就是MVVM

拆出来的ViewModel怎么和外部通讯呢,这时候就回到了我们说的Reactive,iOS中我们使用KVO,Notification,block,delegate和target-action都可以用来做ViewModel和外部的通讯,但是这些都不如Reactive来得优雅,几种方法具体比较大家可以用简单代码实现一下,就会知道Reactive和MVVM是天生一对了,这也是为什么提到MVVM就会提到Reactive了。

总结

还有其他诸如MVCS,MVP,VIPER等架构,有的只是看过一些介绍,有的自己稍微尝试过。得出一个自己的感受

这些架构都是衍生自MVC,把MVC中某个部分拆开,得到一个新的部分,并制定一个规范,然后就形成了新的架构模式

一个APP在设计架构的时候不能拘泥于这些,这些只是你掌握的基础知识。看过一句话,天下架构出自MVC。仔细想想其实有一定道理,因为所有的模式可以抽象成 数据管理者数据加工者数据展示者。MVC其实已经站在了一个很高的角度看问题,所以其实重点是你应该怎么拆,这里我们APP的原则是这样的:

  • 能从controller里拆出去的尽量拆出去,只保留最核心的部分
  • 拆出去的东西能保证有复用性
  • 尽可能的站在更高角度拆分(也就是拆分的粒度尽量大一些,不要拆分成一个个很小功能,不然你工程文件的数量会太大)

这些说的都是相对的东西,不是绝对的。比如,我们APP有一个很简单的页面好友列表,只展示一个头像,昵称,和关注关系,这里有必要去MVVM吗,有必要剥离tableview的各种delegate吗,一个简单的MVC可以说十多分钟就可以写完,完全没必要去用那些技巧。

一个APP的架构设计应该参考自己公司的业务,因为你做出的东西是要为公司业务服务的,脱离了业务去谈架构是空谈。不结合实际情况,拿着一堆理论直接上是很容易出问题的,我们应该在掌握了这些思想的前提下,结合自身公司的业务,灵活使用才是正道啊!

你可能感兴趣的:(浅谈iOS架构(结合公司项目))