拓冰建站拓冰建站
首页 / 资讯中心 / 正文

【听见课堂 HarmonyOS NEXT 实战系列 02】Stage Model 多模块架构:entry、HAR 与 HSP 如何分工

【听见课堂 HarmonyOS NEXT 实战系列 02】Stage Model 多模块架构entry、HAR 与 HSP 如何分工当 HarmonyOS NEXT 项目从单页 Demo 发展成完整应用后最容易出现的问题不是“代码写不出来”而是页面、模型、主题、数据库和系统能力全部挤在entry模块里。短期看起来开发很快后期却会遇到循环依赖、重复类型、组件难复用和安装产物关系不清等问题。听见课堂从项目结构上把职责拆成四个模块entry、common-core、common-ui和shared-business。这篇文章以真实工程为例说明 Stage Model 下如何建立清晰、可验证的模块边界。一、四个模块分别解决什么问题项目的模块关系可以概括为entry ├─ depends on common-core ├─ depends on common-ui └─ depends on shared-business └─ depends on common-core common-core 无业务 UI 依赖 common-ui 无业务数据依赖各模块职责如下模块主要职责不应该放入的内容entryUIAbility、页面外壳、交互状态、路由入口数据库表结构、复杂聚合规则common-core领域模型、路由常量、用户偏好具体页面、设备能力实现common-ui颜色、尺寸、背景等共享视觉资产课程业务规则、数据库访问shared-businessService、Repository、持久化、系统能力封装页面布局和临时 UI 状态边界越清楚依赖方向越容易保持单向。尤其是common-core它应该成为其他业务模块都能理解的稳定语言而不是反向依赖页面或数据库实现。二、entry应该轻但不是空壳entry仍然负责 Stage Model 的应用入口。听见课堂在EntryAbility.ets中先初始化课堂数据再加载首页内容onWindowStageCreate(windowStage:window.WindowStage):void{this.initializeDataAndLoad(windowStage);}privateasyncinitializeDataAndLoad(windowStage:window.WindowStage):Promisevoid{constusingRelationalStore:booleanawaitinitializeClassroomData(this.context);hilog.info(DOMAIN,TAG,RelationalStore active: %{public}s,usingRelationalStore?true:false);windowStage.loadContent(pages/Index);}这里有两个设计点数据初始化属于进入应用前的基础工作但具体数据库创建和种子数据不写在 Ability 内initializeClassroomData返回当前是否启用了 RelationalStore如果创建失败内部切换到内存 Repository再继续加载页面避免把一次持久化异常直接变成白屏。Ability 还要承担前后台生命周期协调。例如项目在进入后台时释放手语相机资源这类和应用生命周期直接相关的动作放在入口层比散落在页面里更可靠。三、HAR 与 HSP 不是同一种复用在这个项目中三个公共模块的产品形态并不完全相同common-core、common-ui适合作为 HAR被编译进使用它们的模块shared-business作为 HSP承载可共享的业务与能力实现。HAR 更接近编译期复用使用方最终会包含相关代码HSP 则是独立共享包运行时由应用模块引用。两者的差别会直接影响安装和交付。例如在全新设备上只安装entry产生的 HAP而没有安装它依赖的 HSP应用可能无法完成正常启动。因此真机验证不能只写一条“安装 HAP 成功”还要记录产物之间的依赖顺序。一个更稳妥的设备验证顺序是hdc list targets-v hdc install-r.\shared-business\build\default\outputs\default\shared-business-default-signed.hsp hdc install-r.\entry\build\default\outputs\default\entry-default-signed.hap实际路径应以当前 hvigor 输出为准。命令写进文章不代表本次写作过程中已经重新安装交付时仍要保留真实终端输出。四、模块依赖应该由包配置明确表达entry/oh-package.json5中通过本地模块路径声明依赖{ dependencies: { heard/common-core: file:../common-core, heard/common-ui: file:../common-ui, heard/shared-business: file:../shared-business } }而shared-business只依赖common-core。这能避免业务层为了使用颜色或页面组件而反向依赖 UI 模块也避免核心模型知道数据库或设备实现。建议为每个模块保留一个统一导出入口例如// common-core/src/main/ets/index.etsexport*from./models/ClassroomModelsexport*from./navigation/Routesexport*from./preferences/UserPreferences统一出口能减少跨模块调用方对内部文件位置的依赖。未来移动内部目录时只要公共导出保持稳定页面代码通常不需要跟着大面积修改。五、不要把“共享”理解成“什么都往里放”公共模块最常见的失控方式是出现一个不断膨胀的utils或common。判断代码应该放在哪个模块可以问三个问题它表达的是稳定领域概念还是具体界面它是否需要系统上下文、数据库或设备能力其他模块依赖它后会不会反向引入不需要的实现例如RouteId和TaskItem是稳定领域语言放在common-coreAppColors与AppSizes是共享视觉 token放在common-uiRelationalClassroomRepository需要关系型数据库能力放在shared-business页面选择了哪个 Tab、弹窗是否展开是短生命周期状态留在entry。六、构建通过后还要验证模块产物多模块项目的验证至少包括以下内容ohpm install.\hvigorw.bat assembleHap--mode module-p moduleentrydefault.\hvigorw.bat assembleApp除了命令是否返回成功还要检查entry、HAR、HSP 是否都生成了预期产物HSP 和 HAP 的包名、版本与签名是否匹配全新设备上能否按正确顺序安装并冷启动从后台恢复时相机、语音等资源是否按生命周期重新建立文章或交付说明中是否把“构建成功”和“真机运行成功”分开描述。听见课堂现有结构已经体现了这四层职责但模块边界仍需要通过持续审查来维护。只要页面开始直接访问数据库或common-core开始依赖 ArkUI 页面就说明依赖方向正在变坏。总结Stage Model 的多模块架构不是为了让目录看起来更专业而是为了把生命周期、领域语言、视觉资产和业务实现分开管理。HAR 与 HSP 也不只是两种打包后缀它们会影响依赖方式、产物结构和真机安装流程。下一篇将沿着页面到数据源的路径继续深入分析为什么 ArkUI 页面不应该直接操作数据库以及 Service 与 Repository 如何共同保证业务口径一致。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门