riceIsland

学習メモ・備忘録

← 記事一覧に戻る

アーキテクチャ

内容(取り組んだこと)

Androidアプリのアーキテクチャの公式ガイドを読んで、 Afrelを公式ガイドで推奨されているアーキテクチャに沿う形にリファクタリングするために、 公式ガイドの通読と現状コードの課題を把握。

1. レイヤードアーキテクチャ

  • UIレイヤ(アプリデータを画面に表示する)

    • UI要素:アプリのデータを画面にレンダリングする(Jetpack Compose)。
    • 状態ホルダー:アプリのデータをUI要素に渡す(ViewModelなど)。
  • データレイヤ(アプリのビジネスロジックを含む)

    • リポジトリ:アプリのデータを一元管理、データソース間の競合の解決、データソースの抽象化、ビジネスロジック。
    • データソース:アプリとシステムの間の橋渡し役。
  • ドメインレイヤ(UIレイヤとデータレイヤの間のオプションレイヤ)

    • 複雑なビジネスロジックや複数のViewModelなどで再使用できる処理があれば単独で保持する。
    • ユースケースやインタラクタなど。

2. 設計思想

  • 関心の分離:責務を分ける。レイヤードアーキテクチャは実際に関心の分離をサポートしている。(UIレイヤとデータレイヤごとに職務が違う)
  • UDF(Unidirectional Data Flow):データを単方向に伝える。データは上位コンポーネントから下位コンポーネントに伝えて、 イベントは下位コンポーネントから上位コンポーネントに伝わるようにする。
  • SSOT(Single Source Of Truth):データの管理が複雑にならないようにしようという思想。永続モデル(ローカルデータ)が推奨されていた。

3. 現状コードの確認

MainViewModel.kt

// アプリデータの取得
val apps: StateFlow<List<App>> = appRepository.getAppsForMonth()
val expenditures: StateFlow<List<Expenditure>> = expenditureRepository.getExpendituresForMonth()

// ビジネスロジック
fun addApp(app: App) {
    viewModelScope.launch {
        appRepository.insertApp(app)
    }
}

fun addExpenditure(expenditure: Expenditure) { ... }

アプリの取得とビジネスロジックが混在しており、取得したデータを使用する画面とビジネスロジックを呼び出す画面が異なっており、 関心の分離にしたがっていない。1ViewModel = 1画面が理想。

独り言

SSOTとして永続モデルが推奨されていたが、なぜ推奨されていたのかは覚えていない。見返してもどうせ忘れるので、実践というかなぜ推奨しているのかを言葉で理解するのは難しいのだと思うから、 実際に図解化するもしくはこのプロジェクトのSSOTはどこかをClaude Codeに聞いて理解する。