如何深度重构UIViewController实例-直播界面
之前写过一篇,中间简单的提到过我现阶段是如何重构Controller这一层的。之后不少同学联系我索要demo代码,果然是no code, no BB。
抽空把之前做过的一个直播App Controller这一层抽离出了一个简单的demo,把关键的和业务相关的代码全部去掉了,剩下一个列表和直播界面,但能从中看出完整的流程。
重构思路
重构的思路在之前的文章已经做过详细介绍,可以下图归纳:
分为Controller,View,Presenter,Interactor,Adapter。Controller和View同MVC,Presenter配合Category语法负责业务逻辑和状态维护,Interactor做页面路由,Adapter处理UITableView的DataSource和Delegate。
附上代码之前,再啰嗦几句分享下我对于Controller这一层代码的看法。
减少体力劳动
Controller这一层里面有相当多的体力劳动,每做一个新feature,就要新建一些Controller相关的类,UIViewController,Presenter,UIView,UITableVIew,DataSource,Delegate等等,我想过很多办法来减少这些体力劳动带来的损耗。
比如使用一些第三方的Xcode插件,用Peckham做头文件快速导入,用KSImageNamed书写UIImage,甚至还自己做了一款FastStub来生成一些常用代码,情况有所改善,但效率还是不够高。
再后来想通过脚本来一键生成Controller,现阶段流行的各种MVX系列,提供了一定程度的抽象,但具体到项目当中需要明确哪些代码是每次都重复敲写的,不同的Controller复杂度不一样,所需要的类单位,粒度大小都不一致,所以在写脚本之前,需要先对Controller做归类分析。
Controller分类
从2010年开始新建第一个UIViewController文件,到今天已经记不清有多少个了。做过的业务也非常之多,总体感觉下来,从复杂度的角度来说,可以将Controller分为以下三类:
第一类,简单静态Controller
这类Controller没有多少复杂的业务代码,大部分时候是静态展示,或者是用户点个按钮触发一个页面跳转这一类,比如App的About页面,Privacy页面,或者是简单的Profile页面,这些页面简单到一个xib文件,加上一个UIButton回调就结束了。这类Controller的代码几乎一目了然,甚至不需要用什么MVP,MVVM来做重构,维护起来也是砍瓜切菜一样轻松。
第二类,中等复杂度业务型Controller
这类Controller有一定量的业务代码在其中,而且未来也有进一步增长的可能性,使用自带的MVC已经不能很好的应付复杂度。这类Controller占用了我们绝大多数的编码和debug时间,也是平常技术圈讨论MVX系列的原动力。我这几年新建的UIViewController大部分都属于这一类,
这类Controller我现阶段是使用之前文章中提到过的CDD来做重构的,总体来说是部分参考MVP,部分参考VIPER,再结合我自己的经验做了一些功能类的划分,将每次新建Controller所做的重复工作都用模板保存了。
这类Controller再细一点来说还可以分为两类,带UITableView和不带UITableView的,如果带UITableView,我会在脚本里把UITableView的创建,datasource,delegate的设置,cell的绑定等等一并做好,UITableView相关的代码我也敲到快要吐了,所以用脚本生成之后,有种说不出来的轻松感。根据是否带UITableView,我做了两个模板:
不光节省了很多新建文件,串联各个类的劳动,还把团队的架构达成了惊人的一致,每个人的代码看起来都像是同一个人写的一样。模板中各个类的用处,可以参考我之前架构分析的文章。
第三类,极度复杂重业务型Controller
这类Controller往往是App的核心功能所在,业务重度堆积,且随着每个版本的迭代会进一步的膨胀。我之前举例过直播界面的例子,
这类Controller往往比较少,所以不需要特别的模板来生成,在第二类Controller模板的基础之上做一些定制就行了。主要是使用Objective C当中的Category语法,对Presenter做进一步的业务划分。View的复杂度可以通过CDD来解决,不清楚CDD的可以参考这篇博文,下图就是demo当中的直播Controller结构:
可以看到EStreamPresenter+Gift这样一个拓展,以及View目录下各个子View的划分,我们可以根据业务的复杂度进一步的增加Category和子View的数量,不会导致结构的失控,也不需要在维持架构的清晰上写额外的代码。
按需定制
上述结构以及demo中的模板,只是我根据过往经验所做的高度抽象,大家也可以按照自己的理解和方式来做定制,Template相关的代码都在Resource目录下。重点在于避免平常工作当中的重复体力劳动。
顺道安利下demo当中这一套重构Controller的方式,多年含着泪摸爬滚打总结出的经验。具体demo的代码就不放github骗星星了,感兴趣的同学可以在公众号回复c,获取demo的压缩包,可以直接运行。
欢迎关注公众号:MrPeakTech