iOS 组件化+热切换+热更新+MVVM 架构思想漫谈

移动互联网发展10余年来,移动应用也谁之发生了翻天覆地的变化。从最初的几M小应用到现在动则几十上百M;从最初的一个人几个小功能,到现在的几十上百号人,比PC网页还要齐全还要强大的功能。在此过程中,原有的单Project,MVC架构,一个月一发版,已经远远不能满足当前移动应用的开发。于是乎,一个新的名词便诞生了–移动架构师。

总有开发者朋友问我,得具备什么样的水平,多长的工作经验,做过多大的项目才能成为一个架构师啊。的确,这个问题很难回答。架构,在很大程度上并不具有具体的角色定位,架构师亦然。能够独立做出一个APP,可以称为这个APP的架构师。能够把控一个超级APP的所有技术解决方案,可以称为这个超级APP的架构师。

总有开发者朋友问我,什么样的架构才是好架构。在很长一段时间,C/S架构独领风骚,随后B/S架构横空出世,一时风头无两,但是随着移动互联网的出现和发展,C/S架构又成为移动应用的主流,再次焕发初生命地光彩,重拾其荣耀,但与此同时B/S却也依然坚挺。这就是架构,只有适合,没有好坏。

同样,我们今天所谈论的这套宏伟的iOS架构,是绝对不适合只有几个页面的小APP的。至于如何抉择,3人以上的开发团队可以组建化,百万级别日活可以热切换,百万级别用户量可以热更新,需求频繁、功能分布零散,高耦合可以用MVVM。

数据持久化方案,网络方案,MODEL方案,这些也是架构,怎么今天不谈呢?因为这是技术,而我们今天所谈论的是思想。

APP组件化,我总结了两种方案。总线+分线、分线+分线。第一种,总线+分线方案,对应IOS APP,即多个子模块加一个主模块,主模块负责所有子模块间的组合和通信,必不可少;第二钟,分线+分线,即任意两个子模块都可以组合构成一个独立的APP。对于这两种方案,第一种便于理解和实现,第二种灵活性更高,优势虐势都很明显,至于取舍,选则自己擅长的便是。

APP组件化的具体实现,我推荐使用 CocoaPods私有Pod 来实现各个组件,理由有下,技术成熟、资料众多,使用者众。具体实现方式亦有两种。
第一种,将各个组件做为LocalPod,方便调适,维护。
第二种,像第三方Pod一样作为外部组件引入,优势是便于把控。同时,这两种方式也可以结合使用,与业务毫无关联的基础组件,可以作为第三方Pod引入,由团队专人维护,而将业务模块作为LocalPod引入,可以方便调适、维护。
至于具体实现,请参看文章末尾的Git项目。

APP热切换,即在用户使用APP的过程中,出现某一个或者多个功能无法使用时,直接将该功能切换为React-Native的实现,或者H5的实现。前提是你有React-Native或者H5的备份可供下发,并且APP提供了所有正常功能的访问权限和方法。实现难度不高,但是成本巨大,除非著名大厂高日活APP,否则没有太大的实现必要。唯一一点实现难度,主要体现在各端数据格式的统一。打个比方,如果你的一个页面出现了Bug,并且该页面为了用户体验是使用原生编写,而该页面的必要初始化参数通过上一页面带入,此时你临时将页面切换成RN或者H5的实现,则你所传递的参数必定要被其数据结构所认可。所以,如果要实现APP的热切换,最好是各个功能、页面都只使用一个identity字段作为初始化的请求参数。至于具体实现,请参看文章末尾的Git项目。

APP热更新,即无需发版,可做紧急Bug修复,和功能更新,在去年早些时候还有JSPatch等直接替换OC方法的方案来修复Bug,但是很不幸,现在已经被苹果所禁用。目前主流的方案是使用RN构筑View和实现业务逻辑,然后做有限的功能更新、和Bug修复,即通过RN对你APP所有原生功能做重新的排列组合,而修复一些不是由你的原生基础库所导致的Bug。目前主要有两种实现方案,一种是原生提供所有的基础功能和库,由RN实现页面和业务逻辑,需要从零开始开发;另一种是把RN作为一个组件,植入到现有原生APP中,并为RN提供主要原生页面和功能的访问支持,部分业务场景使用RN编写,这样实现有点类似于原生+H5,优点是性能高于H5,缺点是成本比H5更大。

MVVM架构,即Model-View-ViewModel的分层架构方案,但凡对架构稍有了解的都不会觉得陌生。但在iOS项目的具体实现中ViewController绝对是必不可少的,所以我们在iOS项目中也不妨将它理解为Model-View-ViewModel-ViewController。Model、View这两层一个是实体模型,一个是显示和操作实体模型,在实际情况中Model中的数据和View中的数据往往存在差异,比如Model中有一个100,在View中却要显示为100元,在View中有一个选项菜单,选择的是具体菜单名,在Model中却要保存为菜单名+菜单ID,在Model中有一个详细信息的数组,在View中却要根据该信息的长度来控制列表上不同Cell的高度。在MVC架构中这些操作往往通过Controller来完成,但随着业务的增加Controller却又会变得无比的庞大,并且功能模块难以复用。如果将这些操作交给View让其自己去实现的话又会影响到View的可复用性。所以,为了解决这样的问题,ViewModel便应运而生了,ViewModel主要负责将业务和View关联起来,其本质是对数据流的操作,其关注点亦是数据流。即数据发生改变,ViewModel刷新视图,数据不同VIewModel提供不同的显示方案,用户操作视图,VIewModel更新数据;同一个视图,不同的ViewModel绑定不同的数据便做到了视图的复用;不同的ViewController使用同一个ViewModel便做到了功能的复用和解耦;你也可以将ViewModel理解为对业务的封装;所以ViewModel应当具有如下功能,数据的取得、数据的处理、视图的更新、数据的更新。即,ViewModel应当同时持有View和Model,或者ViewModel应当同时绑定View和Model。第三方开源模块Rective Cocoa,提供非常简便的绑定能力,个人推荐使用。至于具体实现,请参看文章末尾的Git项目。

所谓架构,本质上是为了实现业务而对技术和人员的最有效排列组合。架构思想,则是从哲学的角度对经验的总结和归纳。如果你把代码看成有血有肉有思想的生命,那么,架构思想,即创造代码的哲学。你的代码,即你的思想。

来源