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 和使用方法。

下一步