Skip to content

Packages 概览 ​

介绍 ​

Packages(业务功能包层)包含具体的业务功能包,每个功能包都是一个独立的业务模块。功能包通过 Shared 层定义的契约对外提供服务,通过 DI 注入实现功能包之间的解耦。

设计目标 ​

  • 高内聚:每个功能包内部高度内聚,职责单一
  • 低耦合:功能包之间通过契约解耦,不直接依赖
  • 可复用:功能包可以跨项目复用
  • 独立开发:功能包可以独立开发、测试和部署

内置功能包 ​

HCompass 内置了以下功能包:

功能包职责主要内容
auth认证功能登录、注册、登出等
demo示例功能各种示例页面和功能
main主页功能应用主页
user用户功能用户信息、个人中心等

功能包结构 ​

标准的功能包结构如下:

packages/
└── user/                       # 用户功能包
    ├── navigation/             # 导航构建器
    ├── services/               # 服务
    │   └── UserServiceImpl.ets
    ├── view/                   # 页面
    │   ├── UserProfilePage.ets
    │   └── UserSettingsPage.ets
    ├── viewmodels/             # ViewModel
    │   ├── UserProfileViewModel.ets
    │   └── UserSettingsViewModel.ets
    ├── models/                 # 数据模型(可选)
    │   └── UserModel.ets
    ├── components/             # 组件(可选)
    │   └── UserAvatar.ets
    ├── utils/                  # 工具(可选)
    └── UserModule.ets          # 功能包生命周期

目录说明 ​

  • view/:页面组件,负责 UI 渲染
  • viewmodels/:视图模型,封装业务逻辑和状态管理
  • services/:服务层,处理数据获取和业务操作
  • models/:数据模型,定义数据结构
  • components/:功能包内部的组件(可选)
  • utils/:功能包内部的工具函数(可选)
  • xxxxModule.ets:功能包生命周期,导出符合规范的功能包实现

MVVM 架构 ​

功能包内部采用 MVVM(Model-View-ViewModel)架构:

View (页面)
  ↓ 绑定
ViewModel (视图模型)
  ↓ 调用
Service (服务)
  ↓ 操作
Model (数据模型)

职责划分 ​

  • View:仅负责渲染,不包含业务逻辑
  • ViewModel:封装所有业务逻辑,管理状态
  • Service:处理数据获取和业务操作
  • Model:定义数据结构

功能包的生命周期 ​

1. 创建功能包 ​

在 packages/ 目录下创建新的功能包目录。

2. 定义契约 ​

如果功能包需要对外提供服务,在 Shared 层定义契约。

3. 实现功能 ​

在功能包内实现业务逻辑、页面、服务等。

4. 注册功能包 ​

在 Entry 层注册功能包。

5. 使用功能包 ​

其他功能包通过 DI 注入使用该功能包提供的服务。

功能包之间的通信 ​

通过契约和 DI ​

功能包之间通过 Shared 层定义的契约和 DI 注入进行通信:

typescript
// 功能包 A 定义契约
// shared/contracts/IUserService.ets
export interface IUserService {
  getUserInfo(): Promise<UserInfo>;
}

// 功能包 A 实现契约
// packages/user/services/UserService.ets
export class UserService implements IUserService {
  async getUserInfo(): Promise<UserInfo> {
    // 实现
  }
}

// 功能包 A 初始化时注册服务
// packages/user/UserModule.ets
export class UserModule implements FeatureModule {
  registerServices(container: Container): void {
    container.register<IUserService>("IUserService", () => new UserService());
  }
}

// 功能包 B 使用服务
// packages/main/viewmodels/MainViewModel.ets
export class MainViewModel {
  private userService: IUserService;

  constructor() {
    this.userService = getContainer.resolve<IUserService>("IUserService");
  }

  async loadUser(): Promise<void> {
    const userInfo = await this.userService.getUserInfo();
  }
}

功能包的复用 ​

跨项目复用 ​

功能包可以直接复制到其他项目使用:

  1. 复制功能包目录到新项目的 packages/ 目录
  2. 复制相关的契约定义到新项目的 shared/ 目录
  3. 在新项目中注册功能包
  4. 开始使用

最佳实践 ​

1. 保持功能包的独立性 ​

功能包不应直接依赖其他功能包的实现,通过契约和 DI 注入实现通信。

2. 合理划分功能包 ​

按业务领域划分功能包,每个功能包职责单一。

3. 使用 MVVM 架构 ​

严格遵循 MVVM 架构,View 层仅负责渲染,所有业务逻辑封装在 ViewModel 中。

4. 状态管理 ​

使用 V2 版本的状态管理 API(@ObservedV2 / @Trace)。

5. 编写文档 ​

为每个功能包编写文档,说明功能包的用途、API 和使用方法。

下一步 ​