项目大了,编译慢了,开发效率低了,怎么办? 也许你已经知道了组件化,但项目迭代任务紧张,根本没有时间进行总体解耦,更惧怕一会儿改动太大致使的风险不可控,不敢大改,怎么办?git
先别急着放弃,渐进式组件化了解一下github
在实行组件化改造以前,咱们对业内的一些技术文章及开源库进行调研以后,发现基本上千篇一概地都是基于路由这种方案做为通讯引擎来实现组件化,重要的是组件化以前得先解耦原来的项目代码。很尴尬,咱们没那么人力和时间来一会儿作这么一大块事情。这时候咱们是这样想的:web
可不能够先不解耦?windows
这个问题问得好,但是...不先解耦,组件怎么单独以app运行呢?
复制代码
新业务新module能够无耦合,总能够单独运行调试了吧?app
组件须要登陆怎么办?
须要跟其它组件通讯怎么办?
复制代码
用URLScheme来跨app通讯总能够了吧?框架
页面跳转还行,虽然有个中转页面,仅在开发期间使用勉强也能接受
但如何获取服务?那但是要查找接口的实现类,跨app调用时行吗?
复制代码
将须要调用的业务代码一块儿打包总能够了吧?maven
确实能够,但这些代码在哪里?主app module看一下?
难不成要跟主app一块儿打包?没解耦的那些module要所有编译才行哦
复制代码
那...有没有这样一种方案:让咱们能够当即就在新的业务上用组件化的形式进行开发(单组件module以apk的形式编译运行调试,而且能够与其它业务模块互相通讯),享受到组件化编译速度快、调试效率高的好处,又不须要立刻解耦项目,而是在迭代过程当中利用偶尔出现的碎片空闲时间来一个一个慢慢地解耦呢?组件化
好想法,这就是咱们想要的:当即组件化开发 & 渐进式组件化改造
不过很遗憾,好像没有什么现成的方案可用。
那咱们就本身设计一个吧!
复制代码
正式因为项目代码耦合度高,解耦困难,并且迭代任务紧张,没办法单独抽出时间来解耦,致使组件化改造一直停留在口头上。post
为了在不影响业务迭代业务开发的前提下也能用组件化的形式来进行开发,咱们设计了一个支持当即组件化开发 & 渐进式组件化改造的框架:CC(已开源,点这里看源码)测试
以i百联App为例(上海百联集团旗下的一个电商App)来看一下组件化以前项目中存在的耦合状况:
最终项目的耦合状态是这个样子的(一个圆圈表明一个模块,圆圈交叉表明存在耦合状况):
为了能让你们看得清楚,图片上仅仅列出了有限的几个模块,但即便是这样,咱们用一团乱麻来形容它也绝不为过。
咱们的工程师一直是在这样的环境下进行业务迭代开发和bug修复,改代码要当心翼翼,生怕引发其它逻辑出bug,最主要的是开发/调试效率很是低:在使用了maven的状况下,在15吋高配的macbook pro上编译运行每次都要花3-5分钟,在16GB内存的windows台式机上更是动辄10-15分钟,严重影响开发效率,组件化势在必行。
但业务迭代排期时间很是紧张,测试资源不足,咱们须要的是:当即组件化开发 & 渐进式组件化改造
在了解渐进式组件化改造以前,先来看看与之相对的非渐进式组件化改造
非渐进式的组件化方案要求咱们必须在组件化初期当即对项目进行解耦,至少是咱们须要被新业务调用到的组件须要解耦成组件,不然新业务组件脱离主app单独运行调试的时候没法正常工做。
在渐进式组件化的方案中,能够先不用解耦,只须要让单独运行的组件可以调用到主App中的功能便可。思路是这样的:
旁白:
IComponent
接口的实现类,对外暴露自身提供的服务,而且能够独立编译运行调试IComponent
接口实现类,对外暴露自身的服务,让会员积分组件可以跨App调用到这些组件IComponent
接口实现类,对外暴露自身的服务,让浏览记录组件可以跨App调用到商品详情组件IComponent
对应多个组件),等未来有时间了再继续拆分首先,CC的核心通讯引擎采用的不是路由方案,而是组件总线方案(路由 vs 组件总线)
CC采有2套调用流程:App内部组件调用和跨App调用。
框架在接收到组件调用请求时,优先查看当前App内是否有本次CC调用指定的组件
采用组件总线的方案,在App内部调用组件时,等效于直接调用IComponent.onCall(cc)
方法,将调用方设置的调用参数传递给组件,组件执行完以后将执行结果返回给调用方,这个过程当中没有使用反射,执行效率高
在这个过程当中,CC完成了一次调用请求的转发:查找到组件对象,并将调用其onCall方法,将调用参数发送给它,并将组件执行的结果返回给调用方
悄悄地告诉你:CC中自带3种AOP策略,例如动画中显示的CustomerInterceptors
就是其中之二:全局拦截器和针对本次CC调用的拦截器。定义一个拦截器也很简单:实现IGlobalCCInterceptor
接口便可
经过RemoteCCInterceptor
与另外一个App的ComponentService
创建链接,将CC中的调用参数传递给ComponentService
,在ComponentService
中使用这些参数,发起一个App内部的CC调用,最终经过LocalCCInterceptor
调用到IComponent.onCall(cc)
。
组件的执行结果原路返回给调用方
在这个过程当中,CC完成了2次调用请求转发:
能够看出,跨App调用时:
IComponent.onCall(cc)
方法也是在LocalCCInterceptor
中调用,与在App内部调用时同样本文从咱们在实际实施组件化过程当中的一些思考入手,引入了渐进式组件化的概念,介绍了用CC来实现当即组件化开发 & 渐进式组件化改造的实施步骤。
并用动画的方式向你们展现了渐进式组件化与非渐进式组件化的区别以及支撑CC实现渐进式组件化的组件调用流程。
本文中的图片及动画取自上周末(6月9日)在爱奇艺移动技术沙龙分享时的演讲稿,PPT文档可在CC交流群(QQ群:686844583)的群文件中下载,欢迎加群交流。
点击这里了解关于CC的更多内容