您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
移动端组件化架构方案设计

 
作者:廖丹
  706  次浏览      52
2021-2-23
 
编辑推荐:
本文主要介绍了移动端组件化的背景、什么是组件化、组件化架构总体方案设计及核心技术实现等 。
本文来自于开源博客,由火龙果软件Linda编辑、推荐。

一、背景

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

二、什么是组件化

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

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

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

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

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

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

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

组件化架构从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 函数里操作的。目的是提前注册时机,后续任意调用。

1.2 消息总线

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

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

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

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

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

五、总结

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

 

 
   
706 次浏览       52
相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程
最新课程计划
 
最新文章
Flutter-你还在滥用StatefulWidget吗
移动APP安全测试要点
深入浅出 Kotlin 协程
iOS 组件化 —— 路由设计思路分析
移动端跨平台开发的深度解析
最新课程
Android高级移动应用程序开发
Android应用开发
Android系统开发
Android应用高级开发
移动互联网应用开发(iOS,Android,HTML5)
更多...   
成功案例
北京 iOS开发技术深入研究
某企业 Android高级移动应用程序开发
中体彩 Android产品级测试
移动通信 移动互联网应用开发原理
某电力行 android开发平台最佳
更多...