直接跳到内容

仓库层

介绍

仓库层(repository)是数据访问的统一入口。它聚合网络、数据库、本地存储等数据源,对外提供业务语义的方法。业务层只和 Repository 打交道,不直接操作数据源。

设计思路

  • Repository 统一管理数据来源,业务层无需关心数据从哪里来。
  • 支持多数据源组合,如先查本地缓存,再请求网络。
  • 数据源通过构造函数注入,便于测试时替换为 Mock 实现。

网络仓库示例

文件位置:foundation/repository/src/main/ets/GoodsRepository.ets

ts
import { GoodsNetworkDataSource, GoodsNetworkDataSourceImpl } from "@foundation/network";
import { Goods, GoodsSearchRequest } from "@foundation/biz-model";
import { NetworkPageData, NetworkResponse } from "@core/model";

/**
 * @file 商品仓库
 */
export class GoodsRepository {
  private networkDataSource: GoodsNetworkDataSource;

  constructor(networkDataSource?: GoodsNetworkDataSource) {
    this.networkDataSource = networkDataSource ?? new GoodsNetworkDataSourceImpl();
  }

  /**
   * 分页查询商品
   */
  async getGoodsPage(params: GoodsSearchRequest): Promise<NetworkResponse<NetworkPageData<Goods>>> {
    return this.networkDataSource.getGoodsPage(params);
  }

  /**
   * 获取商品详情
   */
  async getGoodsInfo(id: string): Promise<NetworkResponse<Goods>> {
    return this.networkDataSource.getGoodsInfo(id);
  }
}

数据库仓库示例

文件位置:foundation/repository/src/main/ets/DemoRepository.ets

ts
import { DemoLocalDataSource, DemoLocalDataSourceImpl, DemoEntity } from "@foundation/database";

/**
 * @file Demo 仓库
 */
export class DemoRepository {
  private localDataSource: DemoLocalDataSource;

  constructor(localDataSource?: DemoLocalDataSource) {
    this.localDataSource = localDataSource ?? new DemoLocalDataSourceImpl();
  }

  async createDemo(title: string, description: string = ""): Promise<number> {
    return this.localDataSource.createItem(title, description);
  }

  async updateDemo(entity: DemoEntity): Promise<void> {
    return this.localDataSource.updateItem(entity);
  }

  async deleteDemo(id: number): Promise<void> {
    return this.localDataSource.deleteById(id);
  }

  async getAll(): Promise<DemoEntity[]> {
    return this.localDataSource.getAllItems();
  }
}

存储仓库示例

文件位置:foundation/repository/src/main/ets/TokenStoreRepository.ets

ts
import { TokenStoreDataSource, TokenStoreDataSourceImpl } from "@foundation/datastore";

/**
 * @file Token 存储仓库
 */
export class TokenStoreRepository {
  private dataSource: TokenStoreDataSource;

  constructor(dataSource?: TokenStoreDataSource) {
    this.dataSource = dataSource ?? new TokenStoreDataSourceImpl();
  }

  async saveToken(token: string): Promise<void> {
    return this.dataSource.setToken(token);
  }

  async getToken(): Promise<string> {
    return this.dataSource.getToken();
  }

  async clearToken(): Promise<void> {
    return this.dataSource.clearToken();
  }
}

ViewModel 使用示例

ts
import { GoodsRepository } from "@foundation/repository";
import { BaseNetWorkViewModel } from "@core/base";
import { Goods, NetworkResponse } from "@core/model";

@ObservedV2
export default class GoodsDetailViewModel extends BaseNetWorkViewModel<Goods> {
  private repository: GoodsRepository = new GoodsRepository();

  protected requestRepository(): Promise<NetworkResponse<Goods>> {
    return this.repository.getGoodsInfo("1");
  }
}

如何新增仓库

  1. foundation/repository/src/main/ets/ 下新建 XXXRepository.ets
  2. 通过构造函数注入所需的数据源。
  3. 对外只暴露业务语义的方法,不暴露数据源细节。
  4. Index.ets 中导出仓库类。

注意事项

  • 业务层不要直接依赖 network/database/datastore,统一通过 repository 访问。
  • 数据源变化时只改 Repository,避免影响上层业务。
  • 构造函数支持注入数据源,便于单元测试时使用 Mock。