Repository は「永続化の抽象」ではない

DDD の文脈では、Repository はしばしば「永続化の抽象」と説明されます。しかし、この説明を Android にそのまま当てはめると、Repository の責務は一気に分かりづらくなります。

Android アプリの Repository が相手にしているのは、必ずしも「永続化」だけではありません。

  • API 通信
  • ローカル DB
  • キャッシュ
  • インメモリ状態

これらをすべて「永続化」と呼ぶのは、少し無理があります。

本書では、Android における Repository を次のように捉えます。

Repository は、ドメインから見た「データ取得・保存の窓口」である

重要なのは、「どこから取ってくるか」や「どう保存するか」をドメインが知らなくてよい状態を作ることです。


Android における Repository の最適責務

Android の Repository が担うべき責務は、非常にシンプルです。

  • 必要なデータを取得する
  • 必要なデータを保存する
  • データ取得手段の違いを隠蔽する

逆に言えば、次のようなことは Repository の責務ではありません。

  • ビジネス判断
  • 状態遷移の決定
  • UI 表示の都合による変換

Repository が「判断」を持ち始めた瞬間、設計は濁り始めます。

たとえば、

  • この場合はキャッシュを返す/返さない
  • この条件なら空リストにする
  • エラーを成功として扱う

といった判断が Repository に入り込むと、「なぜそうなるのか」を追うのが非常に難しくなります。


Repository にロジックが集まりやすい理由

Repository は、設計が崩れ始めたときに、もっともロジックが集まりやすい場所です。その理由は単純です。

  • ViewModel から直接触られない
  • UseCase の下に隠れている
  • DataSource を束ねている

つまり、「ここに書いておけば怒られにくい」場所になりやすいのです。

しかし、その結果として Repository が次のような姿になることがあります。

  • if 文だらけの巨大クラス
  • 返り値の型が文脈ごとに変わる
  • テストが書きづらい

この状態は、Repository が責務を超えた仕事をしているサインです。


DataSource を分けすぎる問題

Clean Architecture の影響で、次のような構成をよく見かけます。

  • Repository
  • RemoteDataSource
  • LocalDataSource
  • CacheDataSource

理論的には美しく見えますが、Android アプリでは分けすぎが問題になることも少なくありません。

  • ファイル数が増える
  • 処理の流れが追いにくくなる
  • 変更時に修正箇所が増える

重要なのは、「分けた理由を説明できるか」です。

  • 実装差分が本当に大きいのか
  • 将来的に差し替える可能性が高いのか

これらに Yes と答えられない場合、Repository 内に実装を閉じた方が、結果として分かりやすい構造になることも多いです。


キャッシュ戦略とドメイン汚染

Android アプリでは、キャッシュ戦略が避けて通れません。

  • 常に最新を取りに行くのか
  • キャッシュを優先するのか
  • オフライン時はどう振る舞うのか

これらの判断をどこに置くかは、非常に重要です。

本書の立場は明確です。

キャッシュ戦略は Repository の責務だが、その意味づけはドメインに置く

  • キャッシュを使うかどうかの判断理由
  • 古いデータを許容する条件

これらはドメイン側で定義されるべきです。一方で、

  • 実際にどのデータソースを使うか
  • キャッシュの保存・取得方法

は Repository に閉じ込めます。

この分離ができていないと、ドメインモデルが Data 事情に引きずられ、設計が一気に崩れます。


Repository は「薄くていい」が「雑であってはいけない」

Android における Repository は、結果として薄くなりがちです。それ自体は問題ありません。

問題になるのは、

  • 責務が曖昧
  • 判断基準が見えない
  • 返り値の意味が説明できない

状態になることです。

Repository は、

  • 何を返すのか
  • どんな失敗が起こり得るのか

を明確に定義しておく必要があります。ここが曖昧だと、UseCase や ViewModel 側に防御コードが増え、全体が汚れていきます。


この章のまとめ

Repository は、

  • データ取得・保存の窓口であり
  • 判断を持たない
  • だが責務は明確であるべき

という、少し難しい立ち位置にあります。

Android × DDD において重要なのは、Repository を「なんでも屋」にしないことです。

次章では、DI・Hilt と DDD をどう付き合せるかを見ていきます。