Harmony 开发中的三层架构

三层工程结构 是鸿蒙应用开发中推荐的 模块化分层架构 ,主要用于复杂应用的代码组织,强调模块解耦 和复用性 。这一架构与操作系统内核的分层不同,聚焦于 应用工程本身的结构设计。以下是详细的层级说明、依赖规则和实际应用场景分析:


三层工程结构

  • commons(公共能力层):用于存放公共基础能力集合(如工具库、公共配置等)。commons层可编译成一个或多个HAR包或HSP包,只可以被products和features依赖,不可以反向依赖。

  • features(基础特性层):用于存放基础特性集合(如应用中相对独立的各个功能的UI及业务逻辑实现等)。各个feature高内聚、低耦合、可定制,供产品灵活部署。不需要单独部署的feature通常编译为HAR包或HSP包,供products或其它feature使用。需要单独部署的feature通常编译为Feature类型的HAP包,和products下Entry类型的HAP包进行组合部署。features层可以横向调用及依赖common层,同时可以被products层不同设备形态的HAP所依赖,但是不能反向依赖products层。

  • products(产品定制层):用于针对不同设备形态进行功能和特性集成。products层各个子目录各自编译为一个Entry类型的HAP包,作为应用主入口。products层不可以横向调用。

上方的图和解释来源于鸿蒙官方文档 详情看这里鸿蒙三层架构官方文档,下边是自己进行的一个总结,如果有错误欢迎指出。

一、三层工程结构定义

graph TD A[commons] -->|被依赖| B[features] A -->|被依赖| C[products] B -->|被依赖| C B -->|横向依赖| B

1. commons(公共能力层)

  • 定位 :基础能力沉淀层,存放 全局共享工具、通用组件、基础服务。
  • 输出形式 :编译为 HAR(静态共享包) 或 HSP(动态共享包)。
  • 依赖规则 :
    • 不可被反向依赖:commons 层不依赖上层(features/products)。
    • 禁止业务逻辑:仅包含与业务无关的公共代码。

典型内容:

  • 工具类:Logger、NetworkUtils、StorageHelper
  • 通用组件:自定义按钮、弹窗模板
  • 基础配置:全局样式、路由表

代码示例:

typescript 复制代码
// commons/src/main/ets/utils/Logger.ets
export class Logger {
  static info(message: string): void {
    console.log(`[INFO] ${message}`);
  }
}

2. features(基础特性层)

  • 定位 :功能模块集合层,每个模块 高内聚、可独立运行/测试。
  • 输出形式 :
    • 非独立部署:编译为 HAR/HSP 供其他模块复用。
    • 独立部署 :编译为 Feature 类型 HAP(动态按需加载)。
  • 依赖规则 :
    • 可横向依赖:不同 feature 模块可互相调用。
    • 可向下依赖:可引用 commons 层。
    • 不可向上依赖:禁止依赖 products 层。

典型内容:

  • 用户模块:user(登录、个人中心)
  • 支付模块:payment(订单、支付)
  • 内容模块:content(文章、视频)

代码示例:

typescript 复制代码
// features/user/src/main/ets/LoginPage.ets
import { Logger } from '@commons/utils/Logger';

@Entry
@Component
struct LoginPage {
  build() {
    Column() {
      Button('登录')
        .onClick(() => {
          Logger.info('登录按钮点击');
        })
    }
  }
}

3. products(产品定制层)

  • 定位 :设备形态适配层,针对不同设备(手机、手表、平板)整合功能模块。
  • 输出形式 :编译为 Entry 类型 HAP(应用主入口)。
  • 依赖规则 :
    • 不可横向依赖:不同 product 模块间隔离。
    • 可向下依赖:可引用 features 和 commons 层。

典型内容:

  • phone:手机端入口,整合全功能。
  • watch:手表端入口,仅集成核心功能。
  • tablet:平板端入口,适配大屏布局。

代码示例:

typescript 复制代码
// products/phone/src/main/ets/MainAbility.ets
import { LoginPage } from '@features/user';

@Entry
@Component
struct MainAbility {
  build() {
    LoginPage(); // 直接复用 feature 模块
  }
}

二、依赖关系与编译配置

1. 模块依赖声明

在模块的 oh-package.json5 中声明依赖:

json 复制代码
// features/user/oh-package.json5
{
  "dependencies": {
    "@commons/utils": "file:../../commons/utils" // 依赖 commons 层
  }
}

2. 编译类型配置

在模块的 build-profile.json5 中定义输出类型:

json 复制代码
// products/phone/build-profile.json5
{
  "apiType": "entry", // 标记为 Entry 类型 HAP
  "buildOption": {
    "artifactType": "hap"
  }
}

三、实际应用场景

场景 1:多设备适配

  • 手机端 (products/phone):集成所有 features。
  • 手表端 (products/watch):仅集成 user 和基础功能。

场景 2:动态功能加载

  • 将低频功能(如 payment)编译为 Feature HAP,用户使用时按需下载。

场景 3:团队协作

  • 不同团队负责独立 feature 模块,通过 HAR/HSP 共享代码。

四、优势与最佳实践

优势 实现方式
模块解耦 严格依赖规则(禁止反向/循环依赖)
代码复用 通过 HAR/HSP 共享公共代码
灵活部署 Entry HAP + Feature HAP 组合
编译加速 独立模块增量编译

最佳实践:

  1. 避免跨层直调:通过接口或事件通信,而非直接引用。
  2. 版本统一管理 :使用 ohpm 管理公共库版本。
  3. 按需拆包:对高频功能使用 HSP 动态加载。

五、常见错误示例

错误 1:反向依赖

typescript 复制代码
// commons 层错误依赖 feature
import { LoginService } from '@features/user'; // ❌ 违反依赖规则

错误 2:循环依赖

graph TD A[featureA] -->|依赖| B[featureB] B -->|依赖| A

解决方案:将公共逻辑下沉至 commons 层。


相关推荐
aqi007 小时前
鸿蒙版本的电子书阅读APP开放源码啦
android·华为·ai编程·harmonyos·鸿蒙
xq952711 小时前
HDC Assistant 插件横空出世
harmonyos
OH_TPC18 小时前
【鸿蒙优选三方库】@ohos/aki:一行代码让 ArkTS 调 C++
harmonyos
wenyiyiyiyiyi19 小时前
我用鸿蒙 ArkTS 写了个自己天天用的备忘录:待办、课表和长期目标,全塞进一块桌面卡片
harmonyos
承渊政道21 小时前
鸿蒙设备远控电脑实测:ToDesk蓝牙键鼠、双模式鼠标、跨端剪贴板,远控电脑更顺手了
计算机外设·电脑·harmonyos·远程工作·todesk
CV工程师丁Sir1 天前
ArkWeb 手记 04|DevTools 调试与缓存清理
java·spring·缓存·harmonyos
程序猿追1 天前
HarmonyOS 6 上做个极简浏览器:Web 组件 + 前进后退 + 加载进度
前端·华为·harmonyos
程序猿追1 天前
HarmonyOS 6 音视频实战:用 AVPlayer 做一个本地音乐播放器
华为·音视频·harmonyos
威哥爱编程1 天前
HarmonyOS 7 多设备 UX 自动检测实战:AppAnalyzer 多设备体检 + 一多工程底线,提前拦截截断重叠大图大字
harmonyos
威哥爱编程1 天前
HarmonyOS 7 安全相机 2.0 实战:数字内容溯源,为拍摄内容提供来源保护
harmonyos