Skip to content

Shared 概览

介绍

Shared(共享契约层)定义功能包之间的共享契约。如果功能包需要对外提供服务或资源,都需要在 Shared 层定义好共享业务属性。

设计目标

  • 契约优先:先定义契约,再实现功能
  • 解耦:通过契约实现功能包之间的解耦
  • 类型安全:使用 TypeScript 类型系统确保类型安全

模块组成

Shared 层包含 3 个模块:

模块职责主要内容
contracts契约定义服务接口、数据接口等
state共享状态跨功能包的共享状态
types类型定义通用类型定义

契约定义(Contracts)

什么是契约

契约是功能包之间通信的协议,它定义了服务的接口、方法签名和数据结构。

契约的作用

  • 定义功能包对外提供的服务接口
  • 实现功能包之间的解耦
  • 确保类型安全

契约示例

typescript
// shared/contracts/IUserService.ets
export interface IUserService {
  /**
   * 获取用户信息
   * @returns 用户信息
   */
  getUserInfo(): Promise<UserInfo>;

  /**
   * 更新用户信息
   * @param info 用户信息
   */
  updateUserInfo(info: UserInfo): Promise<void>;

  /**
   * 登出
   */
  logout(): Promise<void>;
}

共享状态(State)

什么是共享状态

共享状态是跨功能包的全局状态,多个功能包可以访问和修改这些状态。

使用场景

  • 用户登录状态
  • 应用配置
  • 主题设置
  • 语言设置

状态示例

typescript
// shared/state/AppState.ets
import { AppStorageV2 } from "@core/state";

@ObservedV2
export class AppState {
  @Trace isLoggedIn: boolean = false;
  @Trace currentTheme: string = "light";
  @Trace currentLanguage: string = "zh-CN";

  static getInstance(): AppState {
    return AppStorageV2.getOrCreate("AppState", () => new AppState());
  }
}

类型定义(Types)

什么是类型定义

类型定义是跨功能包共享的数据结构定义。

使用场景

  • 通用数据模型
  • 枚举类型
  • 常量定义

类型示例

typescript
// shared/types/UserTypes.ets
export interface UserInfo {
  id: string;
  username: string;
  email: string;
  avatar?: string;
  createdAt: Date;
}

export enum UserRole {
  Admin = "admin",
  User = "user",
  Guest = "guest"
}

export interface LoginRequest {
  username: string;
  password: string;
}

export interface LoginResponse {
  success: boolean;
  token?: string;
  message?: string;
}

使用示例

定义契约

typescript
// shared/contracts/IAuthService.ets
export interface IAuthService {
  login(request: LoginRequest): Promise<LoginResponse>;
  logout(): Promise<void>;
  isLoggedIn(): boolean;
}

实现契约

typescript
// packages/auth/services/AuthService.ets
import { IAuthService } from "@shared/contracts";
import { LoginRequest, LoginResponse } from "@shared/types";

export class AuthService implements IAuthService {
  async login(request: LoginRequest): Promise<LoginResponse> {
    // 实现登录逻辑
  }

  async logout(): Promise<void> {
    // 实现登出逻辑
  }

  isLoggedIn(): boolean {
    // 检查登录状态
  }
}

使用契约

typescript
// packages/main/viewmodels/MainViewModel.ets
import { getContainer } from "@core/di";
import { IAuthService } from "@shared/contracts";

export class MainViewModel {
  private authService: IAuthService;

  constructor() {
    this.authService = getContainer.resolve<IAuthService>("IAuthService");
  }

  async handleLogin(): Promise<void> {
    const result = await this.authService.login({
      username: "user",
      password: "password"
    });

    if (result.success) {
      // 登录成功
    }
  }
}

设计原则

1. 接口隔离原则

每个契约只定义必要的方法,不要定义过多的方法。

typescript
// 好的设计
export interface IUserService {
  getUserInfo(): Promise<UserInfo>;
  updateUserInfo(info: UserInfo): Promise<void>;
}

// 不好的设计
export interface IUserService {
  getUserInfo(): Promise<UserInfo>;
  updateUserInfo(info: UserInfo): Promise<void>;
  deleteUser(): Promise<void>;  // 如果不是所有使用者都需要,应该拆分
  resetPassword(): Promise<void>;
  sendEmail(): Promise<void>;
}

2. 稳定性原则

契约一旦定义,应保持稳定,不要频繁修改。

3. 类型安全原则

充分利用 TypeScript 的类型系统,确保类型安全。

typescript
// 使用明确的类型
export interface IUserService {
  getUserInfo(): Promise<UserInfo>;  // 明确的返回类型
}

// 避免使用 any
export interface IUserService {
  getUserInfo(): Promise<any>;  // 不推荐
}

注意事项

  • Shared 层不应包含具体的实现逻辑,只定义契约
  • 契约的修改需要谨慎,可能影响多个功能包
  • 使用语义化的命名,让契约易于理解

下一步