5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

DartでKotlinのsealed classを表現する

Posted at

はじめに

Kotlinのsealed classはこんな感じで書けますね。

sealed class SampleResultModel {
    data class Success(val value: String) : SampleResultModel()
    object Error : SampleResultModel()
}

これをDartで表現したいとき、Dartの言語機能にこのようなことを表現できる機能がまだ備わっていないためfreezedというパッケージを使って表現します。
https://pub.dev/packages/freezed

本編

freezedを使って先程のKoltinのsealed classを表現すると以下のよう書き方をします。

@freezed
class SampleResultModel with _$SampleResultModel {
  const factory SampleResultModel.success({
    required String value,
  }) = SampleSuccess;

  const factory SampleResultModel.failure() =
      SampleFailure;
}

使うときはこんな感じで、usecaseなどでdatasourceにアクセスして結果に応じてそれぞれのfactoryを呼んでResultModelを返すことができます。

  Future<SampleResultModel> call() async {
    try {
      final response = await _sampleDataSource.fetchSomeThing();

      return SampleResultModel.success(
        value: response.value,
      );
    } on DioError catch (e) {
      if (e.type == DioErrorType.response && e.response != null) {
        return const SampleResultModel.failure();
      }
    }
  }

更に、DioErrorをcatchすればstatusCodeに応じて各factoryを呼んでResultModelを返すこともでき何のエラーだったのかを判別してUIなどに伝えることができるようになります。

  Future<SampleResultModel> call() async {
    try {
      final response = await _sampleDataSource.fetchSomeThing();

      return SampleResultModel.success(
        value: response.value,
      );
    } on DioError catch (e) {
      if (e.type == DioErrorType.response && e.response != null) {
        switch (e.response!.statusCode) {
          case HttpStatus.preconditionFailed: // 412
            // このケースのreturn
          case HttpStatus.forbidden: // 403
            // このケースのreturn
          case HttpStatus.badRequest: // 400
            // このケースのreturn
        }
      }
    }
  }

UIなどでは受け取ったmodelに対してwhenメソッドがfreezed側で自動生成されてるのでそれを使って成功時はコンテンツを表示して失敗時はSnackbarを出したりなどできるようになります。


        model.when(
          success: (value) {
            // 成功時にvalueを使ってなにかUI表示する
          },
          failure: () {
            // 失敗時はSnackbar表示する
          },
        );
5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?