🎉

HarmonyOS開発実践:ネットワーク層のアート——エレガントなカプセル化と構築ガイド(下)

に公開

まえがき

これまでの2つの記事では、ネットワーク層のカプセル化と最適化のノウハウを深く探りました。本稿では、ネットワーク層の実践アプリケーションに踏み込み、アーキテクチャ設計から具体的な実装まで、丁寧にご案内します。私達が丹精込めて構築したネットワークフレームワークをどのように使うか、ステップバイステップでご説明します。

一、ネットワーク層アーキテクチャ設計

HarmonyOSアプリケーション開発において、ネットワーク層のアーキテクチャが明確で合理的であることは、プロジェクトの保守性と拡張性を保証する鍵です。以下に推奨するネットワーク層のディレクトリ構造を示します。

プロジェクト
|-- network
    |-- data
        |-- models
            |-- params            // リクエストモデル
            |-- responses         // レスポンスモデル
        |-- service             // ネットワークインターフェースの定義
        |-- sources
            |-- remote            // ネットワークデータソース

二、Serviceネットワークインターフェース設計と実装

1. ネットワークインターフェースの構築

インターフェース定数ファイルApiMethod.etsを作成し、すべてのネットワークリクエストのパスを集中管理します。

// インターフェースリクエストパス定数の定義、統一管理と参照を容易にする
const HARMONY_INDEX = "harmony/index/json";
export { HARMONY_INDEX };

2. ネットワークリクエストクラス

ApiRequestクラスは、ネットワークリクエストの中心的な役割を果たし、ネットワークライブラリの初期化、設定、リクエストの呼び出しと組み立てを担当します。

type DataClassConstructor<T> = ClassConstructor<ApiResult<T>>;
export class ApiRequest{

  private static instance: ApiRequest


  static getInstance (): ApiRequest {
    if (!ApiRequest.instance) {
      ApiRequest.instance = new ApiRequest()
    }
    return ApiRequest.instance
  }

  net : NetworkService

  constructor() {
    this.net =  new NetworkService("https://www.wanandroid.com/ ");
    this.net.dataConverter = new JsonDataConverter()
    this.net.addInterceptor(new DefaultInterceptor())
  }

  public getService() : NetworkService{
    return this.net;
  }

  private plainToClassApiResult<T>(ctor: DataClassConstructor<T>, data: object) : ApiResult<T>{
    return plainToClass(ctor,data,{
      enableImplicitConversion: false,
      exposeDefaultValues: true,}) as ApiResult<T>;
  }
  async requestHarmonyIndex(harmonyIndex: HarmonyIndexParam): Promise<ApiResult<HarmonyIndexResponse>> {
    let data =  await ApiRequest.getInstance().getService().request({
      act : HARMONY_INDEX,
      expectDataType : http.HttpDataType.OBJECT,
      queryParams : new Map(Object.entries(harmonyIndex)),
      method: RequestMethod.GET
    })
    let result :ApiResult<HarmonyIndexResponse> = this.plainToClassApiResult<HarmonyIndexResponse>( ApiResult , data.result as object,)
    return result;
  }


}

三、ネットワークデータソース層

1. ネットワークデータソース

BaseRemoteSourceクラスは、基本的なネットワークリクエスト処理と基本的なエラー処理を提供します。これには、ローディングダイアログの表示が含まれます。

// BaseRemoteSource クラスは、基本的なネットワークリクエストとエラー処理を実装します
class BaseRemoteSource {
  async baseRequest<T>(request: Promise<ApiResult<T>>, option?: DataSourceOption): Promise<DataResult<ApiResult<T>>> {
    try {
      // ローディングダイアログを表示する
      NetworkUtil.showSpinner(option);
      const result = await request;
      // ローディングダイアログを隠す
      NetworkUtil.hideSpinner(option);
      // 結果に応じて適切な処理を行う
      return result.errorCode === 0
        ? new SuccessData(result)
        : new ErrorData(new AppBusinessError(result.errorCode!, result.errorMsg!));
    } catch (e) {
      // 異常処理
      const error = e as BaseError;
      NetworkUtil.hideSpinner(option);
      if (option?.showErrorTips) {
        LibToast.show(error.message);
      }
      return new ErrorData(e);
    }
  }
}

2. ネットワークデータソースの実装クラス

WanRemoteSourceクラスはBaseRemoteSourceを継承し、具体的なネットワークリクエストを実装します。

// WanRemoteSource クラスは、特定のビジネスのネットワークリクエストを実装します
class WanRemoteSource extends BaseRemoteSource {
  async requestHarmonyIndex(harmonyIndex: HarmonyIndexParam): Promise<DataResult<ApiResult<HarmonyIndexResponse>>> {
    const option = new DataSourceOption();
    option.showSpinner = true;
    return this.baseRequest(ApiRequest.getInstance().requestHarmonyIndex(harmonyIndex), option);
  }
}

3. データリポジトリ

WanResponsitoryクラスはデータリポジトリとして機能し、リモートデータソースとローカルデータソースの間の調整を担当します。

// WanResponsitory クラスはデータリポジトリパターンを実装します
class WanResponsitory implements IWanSource {
  private static instance: WanResponsitory;
  private remoteSource: IWanSource;

  private constructor() {
    this.remoteSource = new WanRemoteSource();
    // ...(省略部分コード)
  }

  public static getInstance(): WanResponsitory {
    if (!WanResponsitory.instance) {
      WanResponsitory.instance = new WanResponsitory();
    }
    return WanResponsitory.instance;
  }

  requestHarmonyIndex(harmonyIndex: HarmonyIndexParam): Promise<DataResult<ApiResult<HarmonyIndexResponse>>> {
    return this.remoteSource.requestHarmonyIndex(harmonyIndex);
  }
}

四、ページビジネスエンドの使用

ページビジネスロジックでは、データリポジトリのメソッドを呼び出してネットワークリクエストを実行し、返された結果を処理します。

// ページ内のボタンクリックイベントの処理
Button('ネットワークリクエスト')
  .attributeModifier(new ColumnButtonStyle)
  .onClick(() => {
    WanResponsitory.getInstance().requestHarmonyIndex(new HarmonyIndexParam()).then((value) => {
      if (value instanceof SuccessData) {
        const data = value as SuccessData<ApiResult<HarmonyIndexResponse>>;
        LibToast.show(`表示:${data.data?.data?.links?.name}`);
      } else if (value instanceof ErrorData) {
        const error = value.error;
        if (error instanceof AppBusinessError) {
          LibToast.show(`ビジネスエラー:${error.code}`);
        }
      }
    });
  });

おわりに

本稿では、私達が書いたネットワークフレームワークの使用方法について詳しく紹介しました。アーキテクチャ設計から具体的な実装まで、効率的で保守性の高いコードを追求するステップを示しました。これらの知識があなたのHarmonyOS開発をさらに円滑にし、より強固でユーザーにやさしいアプリケーションを構築するのに役立つことを願っています。

Discussion