大型HarmonyOS 项目, 尤其是涉及到多人开发。应像 Android 开发一样,引入组件化开发架构。 用于提升开发效率,和降低维护迭代成本。 我们根据Android组件化架构来对比一下 的看一下 HarmonyOS 组件化架构。
1 HarmonyOS 组件化架构
应用规模扩大和业务需求复杂化导致代码复杂度增加。良好的应用架构设计至关重要,旨在使应用更易于维护、扩展和测试。
在应用开发过程中,经常面临以下挑战:
- 代码组织不清晰,模块间的耦合度高,导致一个模块的变动可能影响其他模块,增加维护难度。
- 应用扩展性不足,添加新功能通常需要大幅修改现有代码。
为了解决这些问题,我们像Android组件化设计一样, 引入 HarmonyOS 组件化设计:
分层架构设计
HarmonyOS应用分层架构包括产品定制层、基础特性层和公共能力层,构建了清晰、高效、可扩展的设计架构。
我们分别从逻辑模型, 开发模型,和部署模型分别介绍应用分层架构设计规则。
逻辑模型
从这张图中, 我们其实可以看到类似于Android组件化的思想, 分层设计和从上到下的依赖关系。具体来看看 官方的定义。
-
产品定制层
产品定制层专注于满足不同设备或使用场景的个性化需求,包括UI设计、资源和配置,以及特定场景的交互逻辑和功能特性。
产品定制层的功能模块独立运作,依赖基础特性层和公共能力层实现具体功能。
产品定制层作为应用的入口,是用户直接互动的界面。为了满足特定需求,产品定制层可以灵活调整和扩展,以适应各种使用场景。
-
基础特性层
基础特性层位于公共能力层之上,用于存放相对独立的功能UI和业务逻辑实现。每个功能模块都具备高内聚、低耦合、可定制的特点,支持产品的灵活部署。
基础特性层为产品定制层提供稳健且丰富的基础功能支持,包括UI组件和基础服务。公共能力层为其提供通用功能和服务。
为了增强系统的可扩展性和维护性,基础特性层对功能进行了模块化处理。例如,应用底部导航栏的每个选项都是一个独立的业务模块。
-
公共能力层
公共能力层存放公共基础能力,包括公共UI组件、数据管理、外部交互和工具库等共享功能。应用可调用这些公共能力。
公共能力层提供稳定可靠的功能支持,确保应用的稳定性和可维护性。
公共能力层包含以下组成部分:
- 公共UI组件:公共UI组件设计为通用且高度可复用,确保在不同应用程序模块间保持一致的用户体验。这些组件提供标准化、友好的界面,帮助开发者快速实现常见的用户交互需求,如提示、警告和加载状态显示,从而提高开发效率和用户满意度。
- 数据管理:负责应用程序中数据的存储和访问,包括应用数据、系统数据等,提供了统一的数据管理接口,简化数据的读写操作。通过集中式的数据管理方式不仅使得数据的维护更为简单,而且能够保证数据的一致性和安全性。
- 外部交互:外部交互负责应用程序与外部系统的交互,包括网络请求、文件I/O、设备I/O等,提供统一的外部接口,简化应用程序与外部系统的交互。开发者可以方便地实现网络通信、数据存储和硬件接入,从而加速开发流程并保证程序的稳定性和性能。
- 工具库:工具库提供一系列常用工具函数和类,如字符串处理、日期时间处理、加密解密、数据压缩解压等,帮助开发者提高效率和代码质量。
开发模型
-
产品定制层
产品定制层的各个子目录会被编译成一个Entry类型的HAP,作为应用的主入口。该层面向多种设备,集成相应功能和特性。产品定制层划分为多个功能模块,每个模块针对特定设备或使用场景设计,并根据产品需求进行功能和交互的定制开发。
说明
- 在产品定制层,开发者可以从不同设备对应的应用UX设计和功能两个维度,结合具体的业务场景,选择一次编译生成相同或者不同的HAP(或其组合)。
- 通过使用定制多目标构建产物的定制功能,可以将应用所对应的HAP编译成各自的.app文件,用于上架到应用市场。
-
基础特性层
在基础特性层中,功能模块根据部署需求被分为两类。对于需要通过Ability承载的功能,可以设计为Feature类型的HAP,而对于不需要通过Ability承载的功能,根据是否需要实现按需加载,可以选择设计为HAR模块或者HSP模块,编译后对应HAR包或者HSP包。
-
公共能力层
公共能力层的各子目录将编译成HAR包,仅产品定制层和基础特性层可依赖,不允许反向依赖。该层提取模块化公共基础能力,为上层提供标准接口和协议,提高复用率和开发效率。
部署模型
应用程序(.app文件)在流水线或应用市场上被解包为N个Entry类型的HAP和N个Feature类型的HAP,根据设备类型和使用场景部署到不同设备,实现多端统一用户体验。
在部署模型中,每个Entry类型的HAP代表了应用的入口点,而Feature类型的HAP则包含了应用的特定功能模块。允许应用能够以模块化的方式适配和部署,从而满足不同设备和场景的需求。
部署模型优化了应用的组织结构,确保了应用在各种设备和场景中的一致性。通过根据设备类型和使用场景区分和部署不同的HAP,用户在任何设备或场景中都能获得统一且高质量的体验。
模块化设计
在大型软件工程中,一般会伴随多团队参与开发。各团队之间以弱耦合方式交互,通过契约化接口定义业务之间的交互,定义业务件的接口,确保各团队业务独立发展,互不影响,实现快速迭代演进。业务模块化是现代软件工程的核心原则之一,通过将大型复杂系统拆解为更小、更易管理和理解的功能模块,提高系统的可维护性和可扩展性。每个功能模块都是独立单元,具有清晰定义的接口和职责,能够与其他模块交互以完成复杂任务。
在HarmonyOS应用开发中,模块化既是设计原则,也是开发实践。该原则要求将应用程序拆分为多个功能模块,每个模块负责特定功能或特性。这些模块可以独立开发、编译和部署,也可以在不同设备上灵活组合和调用。
2 官方示例分析
我们以华为官方的组件化项目为参考:HMOSWorld_HDC2024Case 。来看看在鸿蒙组件化的开发思想,以及如何搭建鸿蒙的组件化项目。
话不多说, 先把项目拉下来, 看一下项目结构
根据文件夹可以看出:
- products 对应产品定制层, 对应为 phone module, 产出 最终的 APP 产物,上传应用市场
- features 对应基础特性层, 对应各个业务模块
- commons 对应 公共能力层, 提供最基础的能力,网络库, 数据库,UI组件库,工具库等。这层与产品业务无关。
整体架构
我们将项目用Trae 打开, 让Trae 帮我们分析一下项目的组件化架构:
prompt:
帮我分析一下这个项目的组件化架构, 并分析一下模块之间的依赖关系。在该目录下面新建一个 markdown文件, 并将分析结果输出该markdown中。
看看Tace的 分析:
架构层次
┌─────────────────────────────────────────┐
│ 产品层 │
│ products/phone │
├─────────────────────────────────────────┤
│ 功能层 │
│ discover │ learning │ topic │ login │
│ challenge │ mine │ conference │
├─────────────────────────────────────────┤
│ 通用层 │
│ uicomponents │ utils │ network │
│ datastore │ audioplayer │ aspect │
└─────────────────────────────────────────┘
模块详细分析
1. 产品层 (Products)
phone 模块
- 路径:
./products/phone - 作用: 主应用入口,负责整合所有功能模块
- 运行时依赖:
@ohos/discover- 发现页面@ohos/audioplayer- 音频播放服务@ohos/learning- 学习模块@ohos/topic- 话题模块@ohos/login- 登录模块@ohos/mine- 个人中心模块
2. 功能层 (Features)
discover 模块
- 路径:
./features/discover - 功能: 内容发现和搜索
- 主要页面:
- FeedWaterFlowView - 信息流瀑布布局
- DiscoverArticleDetail - 文章详情页
- SearchView - 搜索页面
- SearchResultView - 搜索结果页
- 依赖关系:
- 依赖
@ohos/mine模块的LearningResource数据模型 - 依赖
@ohos/uicomponents的 UI 组件 - 依赖
@ohos/utils的通用工具
- 依赖
mine 模块
- 路径:
./features/mine - 功能: 个人中心和用户管理
- 主要导出:
MineView- 个人中心主视图UserModel- 用户数据模型LearningResource- 学习资源数据模型ArticleCardView- 文章卡片组件FeedCardView- 动态卡片组件
- 主要页面:
- ConfirmView - 确认页面
- PhotoView - 照片查看
- SettingView - 设置页面
- UserAccountView - 用户账户
- ThemeConfigView - 主题配置
- MineArticleDetail - 文章详情
- 依赖关系:
- 依赖
@ohos/uicomponents的加载和空状态组件 - 依赖
@ohos/utils的数据源和状态管理
- 依赖
learning 模块
- 路径:
./features/learning - 功能: 学习相关功能
- 主要页面:
- LearningDetailView - 学习详情页
topic 模块
- 路径:
./features/topic - 功能: 话题和标签管理
- 主要导出:
TopicModel- 话题数据模型TagColorMap- 标签颜色映射
- 主要页面:
- pageOne, pageTwo - 话题相关页面
challenge 模块
- 路径:
./features/challenge - 功能: 挑战和任务系统
- 主要页面:
- ChallengeDetailView - 挑战详情页
- 依赖关系:
- 依赖
@ohos/audioplayer的音频播放服务 - 依赖
@ohos/utils的工具类和常量 - 使用 HarmonyOS 系统 Kit (ArkTS, ArkUI, AVSessionKit)
- 依赖
login 模块
- 路径:
./features/login - 功能: 用户登录和认证
conference 模块
- 路径:
./features/conference - 功能: 会议相关功能
3. 通用层 (Commons)
uicomponents 模块
- 路径:
./commons/uicomponents - 功能: 通用 UI 组件库
- 提供组件:
LoadingFailedView- 加载失败视图NoneContentView- 空内容视图ArticleCardButtonView- 文章卡片按钮EyeCountComponent- 浏览量组件NoMore- 无更多内容组件
utils 模块
- 路径:
./commons/utils - 功能: 通用工具类和常量
- 提供功能:
LazyDataSource- 懒加载数据源LoadingStatus- 加载状态枚举CommonConstants- 通用常量BreakpointType- 断点类型Logger- 日志工具ImageUtil- 图片工具WindowUtil- 窗口工具ContinueModel- 续传模型
network 模块
- 路径:
./commons/network - 功能: 网络请求和数据通信
datastore 模块
- 路径:
./commons/datastore - 功能: 数据存储和持久化
audioplayer 模块
- 路径:
./commons/audioplayer - 功能: 音频播放服务
- 提供服务:
AudioPlayerService- 音频播放服务单例
aspect 模块
- 路径:
./commons/aspect - 功能: 面向切面编程支持
模块依赖关系图
graph TD
A[phone 产品模块] --> B[discover]
A --> C[learning]
A --> D[topic]
A --> E[login]
A --> F[mine]
A --> G[audioplayer]
B --> H[uicomponents]
B --> I[utils]
B --> F
F --> H
F --> I
J[challenge] --> G
J --> I
H --> I
K[conference] -.-> I
L[network] -.-> I
M[datastore] -.-> I
N[aspect] -.-> I
架构特点
1. 分层清晰
- 产品层: 负责应用打包和模块整合
- 功能层: 实现具体业务功能,相互独立
- 通用层: 提供基础服务和通用组件
2. 模块化设计
- 每个模块都有独立的
build-profile.json5配置 - 通过
Index.ets文件明确定义模块对外接口 - 模块间通过
@ohos/模块名的方式进行依赖
3. 组件复用
- UI 组件统一放在
uicomponents模块 - 数据模型可跨模块共享(如
LearningResource) - 工具类和常量集中管理
4. 路由管理
- 每个功能模块都有独立的路由配置文件
router_map.json - 支持页面级的模块化路由
5. 依赖控制
- 通用层模块不依赖功能层模块
- 功能层模块可以相互依赖,但需要合理控制
- 产品层统一管理运行时依赖