8.9 KiB
HarmonyOS NEXT 客户端 · 架构设计文档
项目:
harmony-client(ArkTS + ArkUI,SDK 6.0.2 / API 22,仅 phone) 业务形态:对接自有后端的通用业务客户端(HTTP + 鉴权 + CRUD)
1. 背景与目标
本工程从 DevEco 空脚手架起步,目标是建立一套可持续演进、可测试、低耦合的客户端架构骨架,为后续业务开发打底。设计依据来自一轮 deep-research 调研(交叉验证华为官方文档与社区实践,9 条结论全部通过对抗式验证)。
核心决策:
| 决策点 | 选择 | 理由 |
|---|---|---|
| 工程结构 | 官方三层 commons / features / products | 单向依赖、官方白皮书推荐 |
| 模块化 | 单 HAP + 多 HAR | HAR 编译期打包、可裁剪;HSP 仅按需加载 |
| 代码分层 | MVVM + 独立 data 层 | 官方指南 + 网络/数据解耦 |
| 状态管理 | 全量 StateManagement V2 | API 22 下 V2 能力完整,字段级精准刷新 |
2. 模块划分与依赖
harmony-client/
├── entry/ HAP 应用壳 + 业务功能(唯一入口,EntryAbility)
├── common/ HAR 基础设施层(网络 / 日志 / 状态 / 工具,无业务、无 UI 组件)
└── uikit/ HAR 通用 UI 组件库 + 主题(无业务、无网络依赖)
依赖方向严格单向,禁止反向/循环:
entry ──依赖──▶ common
entry ──依赖──▶ uikit
common / uikit 各自独立,互不依赖
- common:
HttpClient、鉴权拦截器、统一错误模型、Logger、SessionStore(PersistenceV2 持久化)、工具函数。 - uikit:主题 token(
AppColor/AppSpacing/AppFontSize)、通用组件(AppButton/LoadingView/EmptyView)。 - entry:应用壳装配、路由、DI 容器、MVVM 分层业务代码。
3. 分层与目录结构(entry 内)
采用官方 MVVM 指南的层优先结构,叠加独立 data/ 层与横切的 router/、di/:
entry/src/main/ets/
├── entryability/
│ └── EntryAbility.ets # 生命周期装配:Logger / ServiceLocator / SessionStore
├── router/
│ ├── RouteMap.ets # 路由名常量 + name→页面 分发
│ └── AppRouter.ets # Navigation 导航封装(push/replace/pop/...)
├── di/
│ └── ServiceLocator.ets # 轻量服务定位器(ArkTS 无反射,手动注册/解析)
├── model/ # 领域模型:@ObservedV2 + @Trace 实体
├── data/
│ ├── api/ # DTO + 请求服务(调 common 的 HttpClient)
│ └── repository/ # 数据仓库契约(抽象类)+ 实现
├── viewmodel/ # @ObservedV2 状态容器(data/loading/error 三态)
├── view/ # 可复用 UI 组件(@ComponentV2)
└── pages/ # 页面,仅编排(组合 view + viewmodel)
单向数据流:
pages → viewmodel → repository(契约) → api → HttpClient → 后端
↑ 状态回传由 @Trace 触发自动刷新
4. 状态管理约定(全量 V2,禁用 V1)
| 场景 | 使用 |
|---|---|
| 组件/页面 | @ComponentV2 |
| 组件内部状态 | @Local |
| 父→子输入 | @Param |
| 子→父输出/回调 | @Event(不用 @Link;需双向时用 @Param 的 !! 语法糖) |
| 类/模型可观察 | @ObservedV2 类 + @Trace 字段 |
| 跨层共享 | @Provider / @Consumer |
| 变化监听 | @Monitor |
| 全局会话 | SessionStore(@ObservedV2 单例,见 common/state/SessionStore.ets) |
| 轻量持久化 | PersistenceV2.globalConnect(...);结构化数据后续用 relationalStore(RDB) |
核心约定:ViewModel 是 @ObservedV2 类,持有 @Trace 的 data/loading/error 三态;页面只读状态、调方法,不直接碰 Repository / 网络层。
5. 网络与数据层
5.1 网络层(common/src/main/ets/network/)
HttpClient:封装@kit.NetworkKit的 http,统一超时/请求头,支持拦截器链。HttpInterceptor:拦截器接口(onRequest/onResponse)。AuthInterceptor:请求前注入Authorization: Bearer <token>;401 时清空会话。
5.2 鉴权流程
请求 → AuthInterceptor.onRequest 注入 token → 发出
→ AuthInterceptor.onResponse 检查 401
→ (当前) 清空 SessionStore,由上层跳登录
→ (TODO) token 刷新 + 原请求重放(防并发刷新),需后端 refresh 接口约定后实现
5.3 Repository 模式
data/repository/中定义抽象类契约,ViewModel 只依赖契约,实现可替换(真实 / mock)。- 用抽象类而非 interface,是为了在
ServiceLocator中做Object → 契约强转时兼容 ArkTS。 data/api/返回 DTO,Repository 负责 DTO → 领域模型 映射。
5.4 统一响应与错误
ApiResult<T>:{ code, message, data },code === 0为成功。ApiError:区分网络异常 / HTTP 状态码 / 业务错误码。
6. 横切关注点
6.1 依赖注入
di/ServiceLocator.ets:Map<string, Object> 单例注册表。启动时在 EntryAbility.onCreate 注册 HttpClient、各 Repository、SessionStore;业务侧 get(key) 后强转。
ArkTS 无反射,用字符串 key + 显式强转;若后续规模增大可引入类型安全的 key 常量或轻量注入容器。
6.2 导航
Navigation + NavPathStack(官方推荐,替代旧 Router)。RouteMap.ets 定义路由名常量与 name→页面 分发;AppRouter 持有全局 NavPathStack 提供 push/replace/pop/popToName/clear。HAR 不承载路由。
6.3 日志
common/logging/Logger.ets:封装 hilog,统一 DOMAIN,后续可加等级开关/上报。
6.4 持久化
PersistenceV2:轻量 KV(token / 用户偏好),@Trace字段自动落盘。relationalStore(RDB):结构化数据(订单、列表缓存等),后续引入。
7. 编码规范
- 状态管理只用 V2:新组件一律
@ComponentV2,禁止混入 V1 装饰器。 - 单向数据流:父→子用
@Param,子→父用@Event;页面不直接改 ViewModel 之外的全局状态。 - 页面只编排:
pages/下只做组件组合与 ViewModel 调用,业务逻辑进 ViewModel,数据进 Repository/Api。 - 跨模块引用走
Index.ets:entry 只import { ... } from 'common'/'uikit',不直接引 HAR 内部路径。 - 魔法值收敛到
uikit/theme/Theme.ets:颜色/间距/字号统一取 token。
8. 演进指南
8.1 抽取 feature HAR(业务领域明确后)
当某个业务领域(如订单、支付)足够独立时,新增 feature_xxx HAR:
feature_order/
├── src/main/ets/{model,data,viewmodel,view,pages}
└── oh-package.json5 (name: feature_order, main: Index.ets)
- 根
build-profile.json5的modules增加该模块。 - 依赖它的模块在其
oh-package.json5增加"feature_order": "file:../feature_order"。 - 依赖方向:
entry → feature_xxx → common/uikit,禁止 feature 之间横向依赖(确实需共享时下沉到common)。
8.2 迁移到 feature-first
当 feature 数量增多、单层目录过深时,可将 model/data/viewmodel/view/pages 按 feature 重组:
ets/features/<feature>/{model,data,viewmodel,view,pages}
ets/shared/… # 跨 feature 共享
迁移原则:先把稳定边界抽 HAR,再在 HAR 内部做 feature 分组。
9. 调研结论摘要与引用
- 官方 MVVM(StateManagement V2)指南给出
model/viewmodel/view/pages分层。 - 官方三层工程结构:commons(禁止反向依赖)/ features / products(不可横向调用),打包形态 HAR/HSP/Feature HAP/Entry HAP。
- V2 装饰器映射:
@State→@Local、@Prop→@Param、@Link→@Param+@Event、@Observed→@ObservedV2+@Trace、@Watch→@Monitor、AppStorage→AppStorageV2、PersistentStorage→PersistenceV2。 - V1/V2 不可混用(编译错误);API 19+ 提供
UIUtils.enableV2Compatibility/makeV1Observed放宽混合约束。
主要引用:
- https://developer.huawei.com/consumer/en/doc/harmonyos-guides/arkts-mvvm-v2
- https://developer.huawei.com/consumer/cn/doc/HarmonyOS-Guides/arkts-decorator-overview
- https://device.harmonyos.com/en/docs/apiref/harmonyos-guides/arkts-v1-v2-update-difference
- https://github.com/openharmony/docs(arkts-v1-v2-migration-application / mixusage / inner-component)
- https://github.com/OpeNopEn2007/arkts-patterns
10. 边界与后续
- 本次为骨架级交付,未实现真实后端对接与具体业务(保留示例链路)。
- 未新增 feature HAR(无业务领域),仅写入抽取指南。
- 未做多设备适配(已确认仅 phone)。
- 后续待办:token 刷新策略、RDB 持久化、自动化测试基建、环境配置注入(BASE_URL)。