业内首个支持渐进式组件化的开源框架
前言
项目大了,编译慢了,开发效率低了,怎么办?
也许你已经知道了组件化,但项目迭代任务紧张,根本没有时间进行整体解耦,更害怕一下子改动太大导致的风险不可控,不敢大改,怎么办?
先别急着放弃,渐进式组件化了解一下
背景故事
在实行组件化改造之前,我们对业内的一些技术文章及开源库进行调研之后,发现基本上千篇一律地都是基于路由这种方案作为通信引擎来实现组件化,重要的是组件化之前得先解耦原来的项目代码。很尴尬,我们没那么人力和时间来一下子做这么一大块事情。这时候我们是这样想的:
可不可以先不解耦?
这个问题问得好,可是...不先解耦,组件怎么单独以app运行呢?
新业务新module可以无耦合,总可以单独运行调试了吧?
组件需要登录怎么办? 需要跟其它组件通信怎么办?
用URLScheme来跨app通信总可以了吧?
页面跳转还行,虽然有个中转页面,仅在开发期间使用勉强也能接受 但如何获取服务?那可是要查找接口的实现类,跨app调用时行吗?
将需要调用的业务代码一起打包总可以了吧?
确实可以,但这些代码在哪里?主app module看一下? 难不成要跟主app一起打包?没解耦的那些module要全部编译才行哦
那…有没有这样一种方案:让我们可以立即就在新的业务上用组件化的形式进行开发(单组件module以apk的形式编译运行调试,并且可以与其它业务模块互相通信),享受到组件化编译速度快、调试效率高的好处,又不需要马上解耦项目,而是在迭代过程中利用偶尔出现的碎片空闲时间来一个一个慢慢地解耦呢?
好想法,这就是我们想要的:立即组件化开发 & 渐进式组件化改造 不过很遗憾,好像没有什么现成的方案可用。 那我们就自己设计一个吧!
正式由于项目代码耦合度高,解耦困难,而且迭代任务紧张,没办法单独抽出时间来解耦,导致组件化改造一直停留在口头上。
为了在不影响业务迭代业务开发的前提下也能用组件化的形式来进行开发,我们设计了一个支持立即组件化开发 & 渐进式组件化改造的框架:CC(已开源,点这里看源码)
快速了解CC
- CC : Component Caller
- 是一套基于组件总线的组件化实施方案
- 一静一动,开发时运行2个app:
- 静:主App (通过跨App的方式单组件App内的组件)
- 动:单组件App (通过跨App的方式调用主App内的组件)
- 支持渐进式组件化改造
- 解耦只是过程,而不是前提
用CC来立即开始组件化开发并渐进式地改造你的项目
先了解一下渐进式组件化改造的概念
以i百联为例(上海百联集团旗下的一个电商App)来看一下组件化之前项目中存在的耦合情况:
- 先是一个启动页(Splash),里面会有一些初始化、加载广告等业务,然后跳转到主页,广告可能跳转到商品详情页、用web模块打开H5活动页,存在不少耦合
- 主页中有:首页、分类、发现、购物车、我的等Fragment页面/业务模块,还要处理push等功能,也会存在不少耦合
- 首页中需要跳转到商品搜索,还有各种业务Fragment/业务模块,需要跳转商品详情、各种列表页、各种活动H5页面,耦合程度非常高
- 很多需要用户登录的功能模块都需要耦合登录模块
- 商品详情页、Web模块等模块几乎所有的业务模块都会用到,耦合程度不言而喻
- 百联到家、奥莱代购、分享、埋点、收银台、LBS、秒杀等等等等
最终项目的耦合状态是这个样子的:
为了能让大家看得清楚,图片上仅仅列出了有限的几个模块,但即使是这样,我们用一团乱麻来形容它也毫不为过。
我们的工程师一直是在这样的环境下进行业务迭代开发和bug修复,改代码要小心翼翼,生怕引起其它逻辑出bug,最主要的是开发/调试效率非常低:在使用了maven的情况下,在15吋高配的macbook pro上编译运行每次都要花3-5分钟,在16GB内存的windows台式机上更是动辄10-15分钟,严重影响开发效率,组件化势在必行。
但业务迭代排期时间非常紧张,测试资源不足,我们需要的是:立即组件化开发 & 渐进式组件化改造
在了解渐进式组件化改造之前,先来看看与之相对的非渐进式组件化改造
非渐进式的组件化方案要求我们必须在组件化初期立即对项目进行解耦,至少是我们需要被新业务调用到的组件需要解耦成组件,否则新业务组件脱离主app单独运行调试的时候无法正常工作。
在渐进式组件化的方案中,可以先不用解耦,只需要让单独运行的组件能够调用到主App中的功能即可。思路是这样的:
- 新业务以组件形式开发
- 新组件需要调用的主App中的业务,在对应的模块中创建一个组件类,对外暴露对应的服务,供其它组件调用,并不需要现在就将这个模块解耦
- 新组件通过跨App的方式调用主App中的组件
- 主App也可以通过跨App的方式调用到单独运行的组件App中的组件
- 在同一个module中可以创建多个组件类,将来解耦时将对应的组件类移动到解耦后的module中即可
动画旁白:
- 接入CC后,我们的项目就已经组件化完成了
- 新业务:会员积分,以组件的形式进行开发:创建一个
IComponent
接口的实现类,对外暴露自身提供的服务,并且可以独立编译运行调试 - 会员积分组件需要用到登录、订单和Web模块的功能
- 在登录、订单、Web模块对应的module或包下创建对应的
IComponent
接口实现类,对外暴露自身的服务,让会员积分组件能够跨App调用到这些组件 - 此时如果我们有时间,可以进行解耦,将相对比较容易解耦的登录模块解耦出来,改造成一个组件
- 这时候又来了新业务:用户浏览记录,仍然以组件的方式开发
- 浏览记录组件需要能打开主App的商品详情页,在商品详情页对应的module或包下创建对应的
IComponent
接口实现类,对外暴露自身的服务,让浏览记录组件能够跨App调用到商品详情组件 - 其它的业务也可以用同样的方式来做
- 利用每个迭代过程中的出现的一些碎片空闲时间,将原来项目中的业务模块逐个从主App中解耦出去变成组件
- 如果遇到有些几个组件暂时无法完全解耦,但如果作为一个整体可以解耦出来,就像动画中示例的商品详情和订单模块一样,可以将它们作为一个整体解耦出来(一个module,多个
IComponent
对应多个组件),等将来有时间了再继续拆分 - 持续地按照这个思路进行解耦,最终目标是将整个项目中的所有业务模块都解耦出来变成组件
CC是怎么做到这一点的?
首先,CC的核心通信引擎采用的不是路由方案,而是组件总线方案(路由 vs 组件总线)
CC采有2套调用流程:App内部组件调用和跨App调用。
框架在接收到组件调用请求时,优先查看当前App内是否有本次CC调用指定的组件
- 有: 执行App内部组件调用流程
- 没有:检查当前app是否开启跨app调用功能:
- 未开启: 返回-5的状态码,代表未找到指定的组件
- 已开启: 执行跨App组件调用流程
采用组件总线的方案,在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转发:将调用参数转发给另一个App
- App内部转发:找到组件对象,调用其onCall方法将调用参数发送给它
可以看出,跨App调用时:
- 调用组件的代码与在App内部调用时完全一样,无需任何改动
- 实现组件的代码
IComponent.onCall(cc)
方法也是在LocalCCInterceptor
中调用,与在App内部调用时一样
总结
本文从我们在实际实施组件化过程中的一些思考入手,引入了渐进式组件化的概念,介绍了用CC来实现立即组件化开发 & 渐进式组件化改造的实施步骤。
并用动画的方式向大家展示了渐进式组件化与非渐进式组件化的区别以及支撑CC实现渐进式组件化的组件调用流程。
本文中的图片及动画取自上周末(6月9日)在爱奇艺移动技术沙龙分享时的演讲稿,PPT文档可在CC交流群(QQ群:686844583)的群文件中下载,欢迎加群交流。
点击这里了解更多CC相关的内容
业内首个支持渐进式组件化的开源框架相关推荐
- 【NLP】FedNLP: 首个联邦学习赋能NLP的开源框架,NLP迈向分布式新时代
文 | 阿毅 两周前,南加大Yuchen Lin(PhD student @USC and ex-research intern @GoogleAI)所在的团队在Twitter官宣开源首个以研究为导向 ...
- FedNLP: 首个联邦学习赋能NLP的开源框架,NLP迈向分布式新时代
文 | 阿毅 两周前,南加大Yuchen Lin(PhD student @USC and ex-research intern @GoogleAI)所在的团队在Twitter官宣开源首个以研究为导向 ...
- Euler 今日问世!国内首个工业级的图深度学习开源框架,阿里妈妈造
千呼万唤始出来!阿里妈妈正式公布重磅开源项目--图深度学习框架Euler.这是国内首个在核心业务大规模应用后开源的图深度学习框架.此次开源,Euler内置了大量的算法供用户直接使用,相关代码已经可在G ...
- 【CV实战】年轻人的第一个深度学习CV项目应该是什么样的?(支持13大深度学习开源框架)...
计算机视觉发展至今,许多技术已经非常成熟了,在各行各业落地业务非常多,因此不断的有新同学入行.本次我们就来介绍,对于新手来说,如何做一个最合适的项目.本次讲述一个完整的工业级别图像分类项目的标准流程, ...
- 医动力Android基于CC组件化框架的探索与实践
为什么要组件化? 医动力App作为公司的核心产品已经有多年历史了,随着版本的不断迭代,功能越来越多,代码量越来越大,不可避免的会产生一下问题: 业务越来越复杂,维护成本高; 业务耦合度高,代码越来越臃 ...
- 业务逻辑组件化android,AppJoint 极简 Android 组件化方案
AppJoint 极简 Android 组件化方案.仅包含 3 个注解加 1 个 API,超低学习成本,支持渐进式组件化. 开始接入 在项目根目录的 build.gradle 文件中添加 AppJoi ...
- 教你打造一个Android组件化开发框架
*本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 CC:Component Caller,一个android组件化开发框架, 已开源,github地址:https://github ...
- 安卓一步一步搭建组件化
安卓组件化的搭建和基本功能的实现 1.组件化是什么? 1.1 了解组件化: 1.2 组件化的基本结构: 1.3 组件化的优点: 2.组件化框架的搭建: 2.1 第一步:搭建基础层 2.1.1 创建co ...
- com 组件调用不起来_AwesomeGithub组件化探索之旅
阅读前请点击右上角"关注",每天免费获取Android知识解析及面试解答.Android架构解析,只做职场干货,完全免费分享! 之前一直听说过组件化开发,而且面试也有这方面的提问, ...
最新文章
- 线性代数:04 特征值与特征向量 -- 特征值与特征向量
- 清华大学软件学院院长王建民:以数字基建为契机,加强工业互联网大数据软件建设...
- Carring data across redirect requests
- java监理的职责_承担监理业务和监理责任的一方及其合法继承人被称为()。...
- 电话开启和电话关闭的命令
- Facebook如何将QUIC应用于数十亿流量传输
- 为什么会出现docker
- C语言 第八章 函数、指针与宏
- [转]由自助餐想到软件团队的管理
- 全球首发!惯性导航导论(剑桥大学)第七部分
- Gstreamer之重置PTS与DTS流程(二十)
- win2003 ent 64 + mssql ent 64
- 查找算法之一 顺序查找
- 【图论】Floyd算法求任意两点间最短路
- Linux基础笔记——RAID
- 并发编程学习之线程8锁
- js中every用法_JavaScript手册 | JS Array 对象中的every()方法 - Break易站
- 半年总结——思想的转变
- 高精度线性恒压源设计及电路分析
- 大学数学建模大赛是用计算机,全国大学生数学建模大赛