- Repository は「永続化の抽象」ではない
- Android における Repository の最適責務
- Repository にロジックが集まりやすい理由
- DataSource を分けすぎる問題
- キャッシュ戦略とドメイン汚染
- Repository は「薄くていい」が「雑であってはいけない」
- この章のまとめ
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 をどう付き合せるかを見ていきます。