文章简介:

本文将从三个方面讲解我们组件化项目。第一部分,我们将介绍组件化的意义和业内组件化的进程;第二方面我们将具体介绍组件化所使用的技术,以及组件化过程中所面对的问题;而第三方面,我们会展示我们组件化的相关成果。

第一部分:组件化意义及业内现状

随着公司的发展壮大,开发的业务线越来越多,我们的开发团队人数将会随之增长。在这种情况下,我们原始的开发架构将无法满足我们的业务需求,将不断的暴露出问题。

就拿淘宝来说,淘宝在13年开启的“All in 无线”战略中,就将阿里系大多数业务都加入到手机淘宝中,使客户端出现了业务的爆发。在这种情况下,单工程架构则已经远远不能满足现有业务需求了。所以在这种情况下,淘宝在13年开启了插件化架构的重构,后来在14年迎来了手机淘宝有史以来最大规模的重构,将其彻底重构为组件化架构。

举个简单的例子:

当小王一个人开发时,随心所欲,代码本地管理都是可以满足开发的。但是随着公司业务、功能不断增加,小李、小张等都陆续加入了团队,为了协作开发,则需要code management、code review、code merge、code standards等等这些辅助的开发工具和规则。但是随着公司继续壮大,code提交数量急剧增大、业务划分越来越独立,review、merge等工作靠一个人已不堪重负,不同业务的代码暴露在整个开发组成员下,代码安全也同样经受着考验,小王刚写完代码,发现已经有20+个提交,刚解决完冲突想要提交,发现又有10+个提交,想死的心都有了,在这种心情下,只想快点解决冲突、快点提交,code merge的问题率也就跟着上升。而打包、测试、UI资源、需求等也有同样的问题,这里就不再赘述了。

那么怎么解决这些问题呢?算法里有一种思想,分而治之,可以很好地概括组件化的思想,既然我们太庞大了,那么我们分为各个小的组件,如果还大,我们继续颗粒化,最终达成一个舒适的开发组大小。彼此之前通过标准的方式互相交流,协作开发;当组成app的时候,通过标准的方式引入,在自己开发一个组件时,根本不用考虑其他的10个还是100个组件,只需要对自己开发的组件负责即可。

业内组件化开发模式其实比较早就建立了,但是在早期探路阶段,由于技术上的不完备,没有前车之鉴,采取的方式多少有些绕弯路。

随着包管理、路由等技术的实现和深化,以蘑菇街的组件化为经典案例,像是阻塞的通路一下打开,各大厂汲取经验纷纷完成了比较稳定的组件化实现,如滴滴的TheOne项目,手淘的Atlas项目,微信小程序的WePY等都有异曲同工之妙。

第二部分:组件化所涉及的技术以及难点

前面也说了,之所以可以实现比较完美的组件化,是因为一些工具、技术得以实现,其中比较重要的技术点如:pod库管理工具、路由router、runtime的组件间调用、生命周期分发等。

1、pod库管理工具:

cocoapods官网: https://cocoapods.org

对于pod来说,他解决了我们组件的空间隔离和引入组装问题。
我们实际上是需要它两方面的知识:

  • 怎么使用库
  • 怎么建立库

会使用PPT做炫酷的展示和开发一个有这些功能的PPT程序是完全不同的东西,所以官网也给了两套document。

介绍pod完全可以花3个篇章来写,即怎么使用库、怎么建立库、怎么使用建立的私有库,这里直接有我写好的分享文章,欢迎查看,而这里由于篇幅问题,就不详细说了:

https://blog.csdn.net/zramals/article/details/81219721
https://blog.csdn.net/zramals/article/details/81388703

2、路由

路由是组件化的中间件技术,他解决了我们组件化的耦合问题,它的存在使我们空间隔离组件成为可能。
举个栗子:

当我们想跳转一个A页面的时候,通常来讲我们需要import A页面的头文件,在写相应的跳转方法,但是这样,我们就耦合了A文件,也就无法与之独立,如果A页面是其他业务的文件,那么我们将与其他业务耦合,这样千丝万缕的联系,使我们整个工程根本无法独立拆分。

而路由的出现,帮助我们斩断最后一丝乱麻。

  • 传统路由方式JLRouter:
    JLRouter是比较稳妥的路由方案,他通过url映射block的方式,将行为和url进行连接,大多数的组件化工程都是基于这种路由方案进行的重构。这种方案简单易懂,但是要维护一个全局的url list,并且作为url的参数只能是简单类型,但是这些问题并不影响他发挥的作用。
    这里就有很好的介绍文章:

    https://www.jianshu.com/p/5d621b433c51

  • iOS OC特性runtime-CTMediator:
    在组件化之初,个人是十分喜欢使用新技术的,所以在技术选型时,我并没有采用传统的url Router方案,而是使用了一种新的Target-Action,完全解耦的,且可以传复杂参数的runtime方案-CTMediator,该方案是iOS OC语言的特性,充分利用了该语言最大的runtime特性,在运行期间确定调用的对象,完全解耦合,不需要任何list文件就能做到调用。

    https://github.com/casatwy/CTMediator
    https://www.jianshu.com/p/9b59b51289ef

组件化技术选型的思考文章:

https://www.jianshu.com/p/afb9b52143d4

首先我们将各业务对外的接口封装成独立的库

而在接口中,我们都通过字典的方式进行传参,保证数据类型的多样性;另外我们直接在.h文件中采用markdown语法编写接口文档。

为什么用这种方式呢?我们考虑到文档和文件分离容易造成更新不一致的情况,我们希望尽量减轻开发人员的工作数量,而不是维护多个文件。通常,开发人员直接阅读.h文件即可,但当我们想生成文档的时候,我们只需要将内容拷贝到任意的markdown浏览器,即可以生成一份正式文档:

当我们对外接口编写完毕,我们只需要将这些接口以runtime的方式,连接到对应的方法上面,编译器认可这种运行时的处理方式,不会报错,这时,我们的接口和接口实现就解耦合了,而我们的调用方与实现方也基于此而拆分成功。
接口实现:

具体runtime的实现代码:

这短短的数十行核心代码,使得我们的方法调用通过runtime而解耦合。

3、生命周期分发

将单一工程分成多个独立工程,每个独立工程都有自己的生命周期,则生命周期也存在多个,但是合成一个app时,应仅有一份生命周期。
这个问题也同样包含生命周期文件AppDelegate的还原,在iOS单工程中,我们的初始化工作一般都是放在AppDelegate的启动生命周期didFinishLaunch中,随着开发的进展,这个函数里面的东西会变得非常庞大

这些东西绝大多数并不是业务独立工程所关注的,但是这些代码与启动app息息相关,有些部分例如页面结构,各业务开发时,还是希望存在的,那么怎么做到生命周期仅有一份的情况下,各个独立工程又能共享呢?

我们这里使用了register and dispatch的技术方案,采用register的理由主要是某些业务可能并不需要对生命周期有所操作,那么不管三七二十一一股脑的分发很不合理,加重app负担,所以,有需求则注册,我们只对注册的业务进行生命周期分发,并且根据注册的顺序进行调度,防止生命周期混乱。

目前我们仅注册了平台模块:

这里我们也采用swift的方式重写AppDelegate,以达到提升启动速度的目的。

我们的独立工程只需要copy AppDelegate和plist文件即可,而我们的AppDelegate相信未来也不会有变化,一劳永逸的解决生命周期问题,将处理方式下发给各个子工程。

第三部分:介绍我们组件化的成果

1、1个基础组件库、1个公共业务库、1个DPL视觉库、4个业务库、4个业务接口库、1个主工程

我们从一个git库,分割成12个库,从权限划分、代码安全、代码合并、开发流程都有了相应的脱变。
2、runtime组件调用中间件,包含url remote调用方式,保证未来需求

我们不仅解决我们本地的调用解耦,还为远程调用留下了口子,为未来需求准好准备。
3、life circle下发式管理,主工程生命周期减负,子工程肩负更多责任。
4、独立的jenkins的测试方案,每个子工程不必在等待其他业务完成,测试点完全看自己需要。

5、独立的code权限管理,分group管理权限,不再担心非业务线的开发人员改动自己的代码,提升代码安全。
6、开发人员的分化更加细致,不同级别开发人员肩负不同的责任,不再有权限集中的问题。
7、流水线式开发,组装过程中仅关心成品的组件,不关心具体过程。

8、全部以版本号来控制代码,不再跟具体代码打交道。

而我们的主工程从1300+的文件变为仅存在不足10个文件的壳工程,完全以组装的方式完成App。

展望:

组件化工作任重而道远,后续优化工作也很繁杂,例如资源优化,编译速度优化,安全等,这些工作不做也仅仅是比较麻烦而已,但是解决问题不断进步是技术的永恒追求,希望我们能够将剩下的问题逐步解决优化。

组件化对公司发展至关重要,是一件现在可做可不做,但是如果不做,数年后回首会后悔的战略级项目,很高兴我们最终完成了目标,帮助公司在未来业务发展上减少了技术障碍。

相关文章及引用:

https://www.jianshu.com/p/67a6004f6930
https://blog.csdn.net/fallenink/article/details/52905347
https://www.jianshu.com/p/afb9b52143d4
https://www.jianshu.com/p/9b59b51289ef
https://www.jianshu.com/p/afb9b52143d4
https://github.com/lincode/FRDModuleManager.git
https://github.com/joeldev/JLRoutes.git
https://github.com/casatwy/CTMediator
https://guides.cocoapods.org
https://blog.csdn.net/zramals/article/details/81217761
https://blog.csdn.net/zramals/article/details/81219721
https://blog.csdn.net/zramals/article/details/81388703
https://blog.csdn.net/zramals/article/details/81389256
https://blog.csdn.net/zramals/article/details/81457669
https://blog.csdn.net/zramals/article/details/81663976

宜人贷-iOS客户端组件化介绍相关推荐

  1. 58 同城 iOS 客户端组件化演变历程

    导语: 架构的演进是为业务不断发展服务的,架构不能脱离业务,这是最基本的出发点.58 同城 iOS 客户端随着业务量和用户量的持续增长,架构也是不断受到挑战,采用什么样的架构去适应这些变化,对技术人员 ...

  2. iOS架构-组件化入门(1)

    iOS架构组件化 https://www.jianshu.com/p/2d89f55fc2c4 iOS架构组件化此篇为iOS组件化研究的基础篇,主要是一些组件化的认识,以及益处,必要性. 1.手机淘宝 ...

  3. iOS项目组件化历程

    为什么要组件化 随着业务的发展,App中的页面,网络请求,通用弹层UI,通用TableCell数量就会剧增,需求的开发人员数量也会逐渐增多. 如果所有业务都在同一个App中,并且同时开发人数较少时,抛 ...

  4. 58 同城 iOS 客户端组件体积分析与统计实践

    [导读]目前 58 旗下存在租房.安居客.招聘.二手车.黄页等多个业务线,其中每个业务线在 58 APP 中存在一个或多个业务 pod.在研发层面上,58 同城其实早已实现了并行研发,不过,在并行研发 ...

  5. iOS应用组件化/模块化探究

    组件化是近几年流行起的概念,它是当代码扩张到一定程度时,所采取的一种代码组织架构策略.阿里.蘑菇街等大厂也在近几年陆续完成了其代码组件化的过程. 提到组件化,给人的感觉似乎很高大上,很神秘的感觉.但是 ...

  6. iOS 的组件化开发

    2019独角兽企业重金招聘Python工程师标准>>> 在一个APP开发过程中,如果项目较小且团队人数较少,使用最基本的MVC.MVVM开发就已经足够了,因为维护成本比较低. 但是当 ...

  7. git公有转私有_【IT新手之路】客户端组件化之私有库搭建

    背景 在组件化之前,小花钱包 App 项目代码,在代码结构,代码质量和层级划分上都处于一个比较乱的状态.这样的项目条件在业务发展不是很快的时候,是可以适应需求的,并且能一定程度地保证开发效率.但随着业 ...

  8. android app.build文件_网易友品 Android 客户端组件化演进

    原文作者:简书 - 四单老师 项目背景 主站业务经历了长期的迭代维护,业务的增长同时带来每个版本业务量繁重,迭代周期很快.同时团队也在不断的扩张,对应拆分了组内不同的业务线对接不同业务线的需求,最初的 ...

  9. 基于Qt的桌面客户端组件化框架DT 开源啦

    这个是本人在工作中基于QT开发的组件化桌面开发框架,目前打算开源出来提供给大家,节省大家的开发时间和效率,希望对大家的开发有所帮助,也欢迎提出意见和改进建议 1. 为什么开源DT框架 DT框架,本身就 ...

最新文章

  1. dockerfile指定jvm参数
  2. UA MATH636 信息论5 信道编码简介
  3. 搭建完全分布式的hadoop
  4. VTK:在3DScene显示图表用法实战
  5. .NET Core使用IO合并技巧轻松实现千万级消息推送
  6. c语言计算机动画生成原理,计算机组成原理动画演示系统 - 源码下载|多媒体|源代码 - 源码中国...
  7. 解决HttpServletRequest InputStream只能读取一次问题
  8. python对象回收_python 引用,拷贝,对象回收,弱引用
  9. JMeter中持续时间设置成永远调度器才会起作用
  10. python--二叉树库函数
  11. 写地道的Python
  12. 凸优化系列二:确定步长一维搜索算法
  13. 【特征提取】基于matlab一帧语音共振峰提取【含Matlab源码 1768期】
  14. WBS——工作分解结构
  15. PHP编译安装常见错误解决
  16. linux命令看进程的tcp链接,Linux下查看TCP连接的状态的shell命令
  17. 观察containerd-shim-runc-v2进程与容器里的1号进程
  18. python selenium爬虫 不打开网页 不打开浏览器
  19. ReThought (二): 如何照顾团队中的新人
  20. c语言课程设计之桌面日历(完整源码+注释)

热门文章

  1. 重磅丨十四五国家信息规划:部署了10项重大任务,10项优先行动(附PDF原文)...
  2. 船舶强度与结构设计大作业二matlab,华科船舶结构强度第二次大作业
  3. qutip+mayavi可视化波片对光偏振态的影响
  4. 16 个怪异的代码注释,想用的拿走
  5. 在Mac下使用Charles抓取Android 7.0以上的Https请求
  6. scrapy框架爬取王者荣耀英雄数据
  7. org.springframework.beans.factory.UnsatisfiedDependencyException
  8. KKT condition --- Karush–Kuhn–Tucker conditions
  9. 对于CNN卷积神经网络的前向传播和反向传播的理解
  10. html背景颜色上边白下边红,HTML中,网页正文的默认颜色是红色,背景颜色默认是白色。...