eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

dartのFreezedとPImplイディオムでメンバ保護を行う

前提

Flutterの開発でReduxアーキテクチャを採用している。

Stateの管理に freezed を使うと、簡単な代わりに全てのメンバがpublicになってしまう。

一部のメンバはprivateにしたり、計算済みの値をキャッシュしたい。

改善

概念。

@freezed
class ExampleStateImpl with _$ExampleStateImpl {
  factory ExampleStateImpl({
    /// このデータはpublicにしたくない.
    /// dataListの合計計算は必要になる時まで計算を遅延したい
    required List<int> dataList,
  }) = _ExampleStateImpl;

  const ExampleStateImpl._();
}
class ExampleState {
   // Stateの実装を隠す
   final ExampleStateImpl _impl;

   factory ExampleStateImpl() {
       return ExampleStateImpl._(ExampleStateImpl(dataList: []));
   }

   ExampleStateImpl._(this._impl);

   final int? _dataListSumCache;
   
   int get dataListSum {
      // 合計値を計算して返す。
      // 計算済みのキャッシュがあればそっちを返す
   }

   ExampleState addData(int newValue) {
      return ExampleState(_impl.copyWith(
          // Freezedの機能を使ってデータコピーを返す
      ));
   }
}

実際はもっと複雑なパターンとなるが、Freezedのメンバーを直接見せたくないけどcopyWithの恩恵は欲しい場合に使う。