安居客 Android APP 走向平台化
The following article is from BaronTalk Author 张磊BARON
本文原作者: 张磊BARON,原文发布于微信公众号: BaronTalk
https://mp.weixin.qq.com/s/71VfmQ5ZyihgTwosMPbSmw
安居客 Android App 距离上次的模块化/组件化重构已经两年多了,重构之后很好的支撑了两年多以来的业务发展。但这个世界总是在向前走的,没有任何一种架构能够一劳永逸的解决所有问题,外部环境的不断变化相应的也要求项目架构做出改变,以此来应对环境变化所带来的挑战。
本文分享的就是我们安居客 App 团队这次向平台化转型的背景、转型过程中所面临的问题、挑战、我们的解决方案以及我个人在这个过程中的收获和感悟。
背景
自 18 年以来的市场环境大家都知道,各大公司都在缩减开支、提升组织效率,希望用更少的投入带来更多的产出,以此来应对经济下行带的不确定性。在这个大背景下,集团在 18 年底做出了一系列人效提升、业务整合的动作。
拿房产业务举例: 58 App 里的房产业务之前是由北京的房产团队开发的,而整个安居客 App 是由我所在的上海安居客团队开发的。在这次调整之后,北京的房产团队作为一条垂直业务线来负责 58 App 和安居客 App 中的租房业务的开发,安居客团队则继续负责整个安居客 App (包含新房、二手房、内容、IM 等业务) 的开发,同时还要开发 58 App 中二手房、新房、房产大内容等业务。
在人力不变,工作量翻倍的情况下,我们要如何保证业务的迭代速度不受影响? 由以往的 "单兵作战" 变成了跨团队跨地域协作开发,我们要如何作为一个平台方来和业务方协作开发? 对于 58 App 而言我们是业务方,对于北京房产团队而言我们是平台方,我们要如何同时处理好双重角色?
一次项目重构和架构升级,不只是要解决当下的问题,更要为未来一到两年的业务发展提供支持。为了解决这一系列的问题,我们联合 58 无线团队、58 房产团队、前端、后端多个团队的同学一起发起了 "木星计划",也开启了我们的平台化转型之路。
问题、挑战及解决方案
当公司的业务调整政策下来以后,团队面临的最急迫的一个选择是继续在 58 App 上维护老的房产代码,迭代新功能; 还是将安居客现有业务搬迁到 58 App 实现一套代码在两个 App 里运行呢?
前者我们需要分一半的人力去开发 58 App,这必然导致团队的需求消化量减半,业务迭代速度受影响。好处是暂时不用做任何技术上的改造。 后者需要我们协调 58 无线、58 房产、前后端等多个团队一起对 App 做一次 "大手术",同时还需要说服产品团队容忍改造期间业务迭代速度的放缓。好处是能够一次性将安居客上的房产业务搬迁到 58 App 上,后续我们只需针对房产业务做一次开发就能跑在两个 App 上,用一份人力做了两份的活,开发效率翻倍。
为长远计,我们最终选择了后者。可是要做到一套代码双端运行并不容易,58 App 和安居客 App 隶属于北京、上海两个不同的团队开发,大家底层库不一样,技术方案不一样,开发模式也不一样,要达到我们的目的必然要费一番功夫。接下来我从整体到局部逐步介绍我们在平台化演进过程中的设计思路、遇到的问题和解决方案。
所谓平台化,就是安居客 App 要作为一个平台来对平台上承载的各种垂直业务提供服务,每个服务都需要对上层提供标准化的接口来支撑平台上各类垂直业务的功能。
安居客 App 平台
这一次的项目重构除了要转型平台型 App 支持其他业务的接入和未来业务的发展,还有更重要一点是要做到一套代码在 58 和安居客双平台运行。
要做到这一点,在现有的业务体系和代码体量下虽然工作量巨大,但大的思路确是很清晰简单的:
底层库能统一的尽量统一; 短时间内无法统一的库以及平台特性通过中间层屏蔽平台差异。
安居客 App 架构变化
同时 58 无线团队的同学也改进了他们的架构,和我们一样引入了平台中间层及中间层在 58 App 上的实现,保证安居客业务迁移进来后能正常编译运行。
58 App 架构变化
计算机领域的任何问题都可以添加一个中间层来解决。58 App 和安居客 App 作为两个不同的平台,对业务层提供的能力是不一样的,接口、方法名都是不一样的。同一块业务代码要跑在两个不同的平台,必然要引入一个中间层来抹平差异、屏蔽底层细节,同时对外提供统一的接口供业务层调用。
因此 58 无线团队、58 房产团队和我们安居客团队三方协商,共同制定了一套平台中间层 API,然后两个平台再针对平台中间层 API 做具体实现。
平台中间层设计及示例
为了便于后期管理、划清代码边界,我们将平台中间层服务进一步细化,根据平台差异性将中间层划分为平台公共服务、安居客平台特有服务、58 平台特有服务等。以 Java Package 作为区分, 划分到不同的包结构下。一旦后期某一特有服务变成了公共服务,则将其往平台公共服务迁移。
平台中间层服务划分
在实现上,平台中间层会提供一系列 Service 接口供垂直业务调用,同时提供一个 PlatFormServiceRegistry 类用来注册和获取服务。
public class PlatFormServiceRegistry {
...
/**
* 注册服务
*/
private void registService(Class serviceInterface, Class<? extends IService> serviceImpl) {
if (serviceInterface != null && serviceImpl != null ) {
classMap.put(serviceInterface.getName(), serviceImpl);
}
}
/**
* 获取服务
*/
private <T> T getService(Class<? extends T> service) {
···
IService instance = serviceImplMap.get(service.getName());
if (null == instance) {
try {
Class<? extends IService> serviceClass = classMap.get(service.getName());
if (serviceClass != null) {
instance = serviceClass.getConstructor().newInstance();
serviceImplMap.put(service.getName(), instance);
}
} catch (Exception e) {
Log.d(TAG, e.toString());
}
}
return (T) instance;
}
}
在使用方式上,平台方首先要注册服务。
//注册平台服务
PlatFormServiceRegistry.registeAppInfoService(AjkAppInfoServiceImpl.class);
业务方在使用服务的时候获取到对应的 Service 就可以调用相关方法了。
//使用平台服务
IAppInfoService appInfoService = PlatFormServiceRegistry.getAppInfoService();
appInfoService.getAppName(context);
中间层设计
可以做到完善的降级策略,比如当线上的房源详情页出现了大面积的 Crash,API 可以返回一个 H5 页面的路由协议,临时用 H5 的房源详情页替代; 同时 App 上线 HotFix,等 HotFix 覆盖率达到一定程度后 API 再改回下发Native 路由,跳回 Native 页面; 可以支持新功能的效果验证,利用 H5 和 Native 自由切换这一特性,可以在不发版的情况下验证新功能的数据效果。比如要上线验证某个改动或者某个新功能的效果,之前需要 App 发版,现在只需要做一版 H5 页面,API 直接路由到这个 H5,如果验证下来效果好则可以开发对应的 Native 页面,不好则可以再尝试其他方案; 可以支持平台化改造过程中的灰度上线,这一点放到下一小节详细说明。
持续演进
前面介绍中间层的时候提到,还有一部分底层库暂时无法统一,现阶段是通过引入中间层来解决的。但从长远来看,整个集团无线体系下,依赖的底层库还是要走向统一。就拿分享组件来说,现阶段安居客和 58 都是使用自己的 ShareSDK,然后中间层定义了一套分享接口,两个 App 分别调用自己的 ShareSDK 来实现接口满足业务的分享需求。为了进一步降低开发成本,避免重复造轮子,后期双方还需要统一使用同一个 ShareSDK,抛弃中间层。最终整个集团体系下所有的 App 的架构应该如下面这张图所示:
中间层设计
统一的平台层,不同的宿主搭配上不同的垂直业务,就是不同的 App。这一点还需要我们持续迭代才能做到。
收获和感悟
规范化、流程化
这里说的平台化和文章标题里的平台化不是同一个概念,这里的平台化是指一套系统作为各种 App、Web、小程序等前台应用提供服务;而文章标题里的平台化是指安居客 App 作为一个平台来支持各类房产业务。
当我们能站在这样一个角度看团队的组织结构、研发流程的时候,很多事就更容易理解了。比如中台部门推出了一套日志系统,各个前端团队要不要替换掉自研的埋点库,使用中台部门的服务,我的看法是当然要。让专业的团队做专业的事,中台为各个前端业务团队赋能,无论是质量上还是效率上都会有极大的提升。同时这样也便于对各业务线的用户数据、行为做统一的聚合、分析、报警等等,然后进一步反哺业务。
这也是为什么之前集团 TEG 团队推出 WMDA (58 集团埋点系统) 后,我们要顶住巨大压力在安居客内部推广的原因。
写在最后
平台化改造能顺利完成并非我们一个团队的功劳,这得益于前后端、产品、测试、58 无线、58 房产等多个团队积极的配合,就比如前面介绍的很多技术方案都是 58 无线团队的同学提出并开发的,因此要在这里说一声感谢,我们从兄弟部门学到了很多。
这次平台化改造的过程中涉及了太多的内容,其中每一个点都能拿出来单独写一篇文章,由于篇幅限制并不能在文中一一详述。我们团队在平台化方面的实践上还缺乏足够的经验,个人能力也有限,未能将细节很好的一一呈现。如果大家发现文章中的错误或者实现方案上的不完美,欢迎在评论区留言交流指正。
---------- END ----------
重磅!后厂技术官-技术交流群已成立
扫码可添加后厂技术官助手,可申请加入后厂技术官大群和细分方向群,细分方向已涵盖:Java、Python、机器学习、大数据、人工智能等群。一定要备注:开发方向+地点+学校/公司+昵称(如Java开发+北京+快手+阿信),根据格式备注,可更快被通过且邀请进群
▲长按加群
扫码可添加后厂技术官助手,可申请加入后厂技术官大群和细分方向群,细分方向已涵盖:Java、Python、机器学习、大数据、人工智能等群。一定要备注:开发方向+地点+学校/公司+昵称(如Java开发+北京+快手+阿信),根据格式备注,可更快被通过且邀请进群
推荐阅读
• 字节跳动禁止国内员工访问海外产品代码库,开始恢复在家远程办公
• 知乎热搜!如何看待年仅 28 岁的郭宇宣布从字节跳动退休?
• 再见!刘强东
• 刚刚!美国官宣117000名 IT 人失业,真是史无前例!
最近面试BAT,整理一份面试资料《大厂Java面试通关指北》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 BAT 领取,更多内容陆续奉上。如有收获,点个在看,诚挚感谢 明天见(。・ω・。)ノ♡
• 字节跳动禁止国内员工访问海外产品代码库,开始恢复在家远程办公
• 知乎热搜!如何看待年仅 28 岁的郭宇宣布从字节跳动退休?
• 再见!刘强东
• 刚刚!美国官宣117000名 IT 人失业,真是史无前例!