GTLC全球技术领导力峰会·上海站,首批讲师正式上线! 了解详情
写点什么

移动端组件化架构方案设计

2020 年 12 月 29 日

移动端组件化架构方案设计

一、背景


组件化作为移动端应用架构的主流方式之一,近年来一直是业界积极探索和实践的方向。我们自 2018 年起也在不断尝试各种组件化方案,在智慧政务的多个应用中也进行了实践。我们踩过一些坑,也收获了很多宝贵的经验,并沉淀出了符合我们自身实际业务需求的组件化架构方案。


二、什么是组件化


通常讲到组件化,很多人会认为我们去把一些可以抽象出来的通用的功能模块比如网络库,本地数据存储等等封装出来,以三方库的形式提供给 App 的开发者,这样就算是组件化的开发,严格上来讲,这只能算功能模块的组件化,而我们这里要探讨的是移动端整体架构的组件化,除了提供功能模块的组件化,更多的是强调将 App 的总体业务拆分成不同的业务模块,去实现各个业务模块间的解耦合,甚至包括业务模块和主工程文件之间的解耦合,最终实现业务模块的分布式开发,以及业务模块级别的代码共享。我个人觉得“业务模块化”这个定义相对“组件化”似乎更合适一些。组件强调物理拆分,以便复用;模块强调逻辑拆分,以便解耦。


三、组件化架构总体方案设计


在 App 项目开发中,如果项目比较小,普通的单工程架构就可以满足大多数需求了,但是像大型项目,或者公司 App 数量越来越多时,那原有的单工程架构就不足以满足架构需求了,其存在的问题主要有:


  1. 当项目越来越大时,单工程架构的业务模块间没有明确的划分,模块之前的耦合度大,后期维护成本较高,往往修改一处可能会影响别的耦合模块,出现问题也比较难定位。

  2. 当 App 数量越来越多时,重复工作的可复用性低,即便复用也是代码级的拷贝复用,复用后再修改也需要多处同步更新,不方便同一代码的后期统一升级维护。

  3. 所有模块代码都编写在一个工程中,调试某个模块或功能,需要编译运行整个大的单一工程,编译一次时间很长


为了提升移动端整体的开发效率和产出质量,我们在原有的单工程架构的基础上提出来组件化架构的方案,下面是我们组件化架构的整体分层架构图:



组件化架构从 App 运行时角度来说分为四层,横向层之间是相互不依赖完全解耦的,纵向层之间上层依赖下层,调用下层提供的服务:


业务组件层,整个 App 实际上是由多个业务组件组装而成的,也就是说,在创建 App 时,首先创建一个主工程,然后确认总体业务的拆分,每一个拆分出来的业务组件是一个独立的子工程,主工程负责将所有业务组件当作二方库集成到主工程里,每个子工程可以单独维护、独立编译运行,业务组件之间是完全解耦的。业务组件层的运行依赖下面的三层:


  • 基础组件层,共包括 UI 组件集、数据处理组件集和通用功能组件集。为业务组件层的开发提供具体技术点的支撑。

  • 底层容器层,容器层为整个架构的核心,它是业务组件间解耦合的技术核心,其中路由总线解决组件间一对一的通信(包括页面的跳转和功能函数的调用),消息总线解决组件间一对多的通信,路由总线+消息总线,为组件间的解耦合提供了底层支撑,生命周期的管理解决的是业务组件和主工程之间的解耦合,总结之,底层容器层为组件化框架打好了底层通信基础。

  • 平台系统层,所有的上层封装的组件都依赖于平台系统的接口,这里的平台系统包括 iOS 和安卓。


组件化架构方案的核心在于,将业务按模块划分,通过底层容器和基础组件层的支撑,实现业务模块间的解耦,方便后面的开发和维护,同时,底层容器层和基础组件层作为通用组件沉淀出来复用,后面由专人统一开发和维护,大大节省了实施组的开发工期。下面是基础我们提出来的组件化架构方案落地实施的目标工程结构图:


四、核心技术实现

1、业务模块间的解耦合


传统的 App 架构设计更多强调的是分层,基于设计模式六大原则之一的单一职责原则,将系统划分为基础层,网络层,UI 层等等,以便于维护和扩展。但随着业务的发展,系统变得越来越复杂,只做分层就不够了。App 内各子系统之间耦合严重, 边界越来越模糊,经常发生你中有我我中有你的情况。这对代码质量,功能扩展,以及开发效率都会造成很大的影响,非组件化的架构业务间的相互调用通常会产生如下图所示的强耦合的调用关系:



此时,通常会采取将各个子系统划分为相对独立的模块,通过中介者模式收敛交互代码,把模块间交互部分进行集中封装, 所有模块间调用均通过中介者来做,如下图所示:



这时架构逻辑会清晰很多,但因为中介者仍然需要反向依赖业务模块,这并没有从根本上解除循坏依赖等问题。时不时发生一个模块进行改动,多个模块受影响编译不过的情况。进一步的,通过技术手段,消除中介者对业务模块依赖,即形成了业务模块化架构设计,如下图所示:



通过业务模块化架构,一般可以达到明确模块职责及边界,提升代码质量,减少复杂依赖,优化编译速度,提升开发效率等效果。


我们在具体实现业务模块间的解耦合采用的是路由总线设计+消息总线设计的方式。


1.1 路由总线


路由总线的原则是解除组件间耦合,让 App 业务开发这只需要遵守规则调用,不用关心底层/其它业务的具体实现。内部的路由设计,主要需要解决两个问题:各个组件之间的页面跳转问题和各个组件之间相互调用。通过路由总线的设计,真正确保组件间实现高内聚、低耦合。下面是路由总线的详细设计图:



在具体的技术实现细节上:路由总线是一个单例对象,我们在这里命名为 JXURLRouter,在其内部维护着一个 “URL -> block” 格式的注册表,通过这个注册表来保存所有业务组件服务方注册的 block,以及使调用方通过 URL 映射出 block,并通过 JXURLRouter 对服务方发起调用。并管理该注册表的增删改操作。服务方 URL 的提供可以分为两种:


  • 1、不带返回值的页面跳转;

  • 2、带返回值功能调用。


关于业务组件服务方的 block 何时注册,这里需要在业务组件源文件被加载后,main 函数执行前注册,这样保证 app 启动后的所有业务逻辑里都可以任意调用注册后的服务方,所以注册是在组件源文件的+Load 函数里操作的。目的是提前注册时机,后续任意调用。


拓展


正因为 URL 路由可以发起调用也可以接受返回值,同时 URL 设计可扩展为:通过后台配置某个操作的跳转 URL,URL 如果可以被解析(路由表里能查找到)就直接拿来调用,如果不能被解析就跳转 H5 页面。这样就完成了一个对不存在组件调用的兼容,使用户手中比较老的版本依然可以显示新的组件,不过这还需要 H5 页面功能的配合。


1.2 消息总线


路由总线实现一对一的进行消息派发和调用,如果多次注册同一个 URL,则会被覆盖掉,为满足针对一对多的消息派发,我们增加消息总线的设计,用来做为相互解耦的组件间交互通信的补充。


应用通过消息总线进行事件的中心分发,例如 App 系统用户登录,退出等事件,都可以通过消息总线分发到想订阅此消息的各个组件。


下图是消息总线的详细设计图:


2、业务模块和主工程之间的解耦合


组件之间一对一的页面跳转和功能的调用。解决方案是路由总线,组件之间一对多的消息传递,解决方案是消息总线,那解决完组件间的通信之后,接下来是实现主工程和各业务组件间的业务解耦,也就是生命周期的管理,将主工程中生命周期钩子函数里的业务逻辑处理都下发到各个业务组件中去。


五、总结


移动应用的组件化架构设计,其真正的目标是提升开发质量和效率。单从实现角度来看并没有什么黑魔法,更多的是结合团队实际开发协作方式和业务场景的具体考量,我们建议所有业务模块划分进入稳定期的 App 采用组件化架构设计。即使模块划分还没完全明确,也可以考虑对部分明确了的模块进行组件化改造。因为随着 App 业务的不断迭代累加,团队规模的不断壮大,迟早要用,晚用不如早用。而且目前基于路由 URL 协议注册的模块间通讯方式,对开发效率基本无损。


本文转载自:金科优源汇(ID:jkyyh2020)

原文链接:移动端组件化架构方案设计

2020 年 12 月 29 日 08:001234

评论

发布
暂无评论
发现更多内容

软件架构师的设计语言

dony.zhang

架构师训练营第一周 - 作业

kk

极客大学架构师训练营

如何让自己有机会成为一名架构师?

kk

极客大学架构师训练营

架构师训练营第一周-总结

butterfly

软件架构师应该具备哪些素质?

漫步跑小鸡

架构师训练营第一周-学习总结

海滨

架构图学习总结

阿布

架构师训练营-食堂就餐卡系统设计

架构文档

食堂就餐卡系统架构设计图

阿布

作业二:架构师训练营 -第一周

亮灯

架构师训练营0期Week1作业

theivanxu

极客大学架构师训练营

极客时间-作业一-学习总结

刘柯

食堂就餐系统

安阳

第一周作业一:食堂就餐卡系统设计

Larry

食堂就餐卡系统设计

种个大西瓜

架构师训练营 第一周 总结 架构师与架构

CR

极客大学架构师训练营

架构师训练营-第一周学习总结

架构总结

【架构课作业-第一周】食堂就餐卡系统设计

Nelson

极客大学架构师训练营

架构师训练营0期Week1总结

theivanxu

架构师训练营——食堂就餐卡系统设计

养乐多

【总结】架构师如何做架构

张金峰

极客大学架构师训练营

架构师训练营第1周学习总结

一叶知秋

【第一周】架构训练营总结

星星

架构师第一周作业

suke

极客大学架构师训练营

架构师训练营第一周【学习总结】

小K

极客大学架构师训练营

架构师0期第一周作业(总结)

何伟敏

架构师训练营第一周【作业】

小K

【总结】如何成为架构师

Geek_165f3d

食堂就餐卡系统设计

Arthur.Li

极客大学架构师训练营 UML

第一周作业一:食堂就餐卡系统设计

田振宇

第1周 学习总结

安阳

DNSPod与开源应用专场

DNSPod与开源应用专场

移动端组件化架构方案设计-InfoQ