【習慣トラッカー開発記 #2】アプリ開発の設計と機能の決定

はじめに

前回の記事では、なぜ習慣アプリを作ろうと思ったのか、その背景やテーマ選定の理由を紹介しました。

今回は実際の開発設計について、以下アプリの基盤作りの部分をまとめます。

  • どんな機能を実装するか
  • どのような構成・ライブラリを選定したか
  • どんな環境で開発を進めているか

アプリ設計の方針

個人開発とはいえ、後から機能を追加しやすい構成にしたかったため、アーキテクチャは MVVM + Repository パターンを採用しました。

アーキテクチャ構成

  • ViewModel:UI状態とイベントを管理
  • Repository:データアクセスの窓口(Roomを介してDB操作)
  • Room:ローカルデータベース
  • UI(Compose):状態に応じて描画を自動更新

この構成によって、UI・ロジック・データを明確に分離でき、後からAPI通信などを追加する際にも影響範囲を限定することができます。

パッケージ構成

パッケージ階層は以下のように整理しました。

特に冗長にならないように各ファイルどんな役割かを意識して構成を考えました。

jp.co.xxxxx.habit
│
├── ui/
│   ├── today/
│   │   ├── XXXFragment.kt    // 画面単位にFragmentを作成・配置
│   │   ├── XXXScreen.kt      // 画面単位のComposable
│   │   ├── XXXViewModel.kt   // 画面単位のViewModel
│   │   └── model/            // 表示用データモデル(UI Model)
│   ├── home/
│   │   └── HomeFragment.kt     
│   ├── habit/                // 登録・編集・習慣用
│   ├── category/             // カテゴリ一覧、編集、選択
│   └── settings/
│
├── data/
│   ├── repository/
│   ├── local/
│   │   ├── database/
│   │   │   ├── XXXDao.kt
│   │   │   └── AppDatabase.kt
│   │   └── model/              // Entity
│   └── model/                   // ドメインモデル
└── di/
    └── AppModule.kt              // Hilt用DI設定

UI構築:Jetpack Compose

UIレイヤーには Jetpack Compose を採用しました。

アプリの各画面は Scaffold をベースに構成し、TopAppBar、FloatingActionButton、Card などのMaterial Design 3 コンポーネントで統一しています。

状態管理と依存性注入:MVVM × Hilt

ビジネスロジックは MVVM(Model-View-ViewModel)アーキテクチャで構成しています。 UIはViewModelが持つ StateFlow を購読し、リアクティブにUIが変化するよう設計しました。

しかし、初期はViewModelとのStateFlow連携にやや戸惑う部分もありました。 慣れてくると、状態駆動のUI更新が非常に直感的に感じられました。

また、依存関係管理には Hilt (Dagger) を導入。Repository・ViewModel・Daoの依存を自動的に解決することで、テスト容易性と保守性を高めています。

開発初期はViewModelにRepositoryを直接渡す構成も検討しましたが、スケーラビリティを考慮してHiltを導入しました。

また、シンプルにViewModelのみで進める方法もありますが、今後「習慣達成ログ」や「統計グラフ」などデータの流れが複雑化することを見越して、Repository層を挟むMVVM構成を採用しました。

永続化:Room + Coroutines

習慣データはRoom Databaseで永続化しています。 data classでテーブル定義を行い、DaoにCRUDをまとめることで、コード量を抑えつつ型安全なDB操作を実現しました。

また、DB操作は Kotlin Coroutines を用いて非同期処理化しています。 そして、Flowで習慣リストを監視し、DB更新がリアルタイムにUIへ反映される仕組みを採用しています。

この構成により、「チェックを押すと即座にUIが変わる」ようにユーザビリティを損なわず実装ができています。

ログ・デバッグ:Timber

開発・運用フェーズでのログ出力には Timber を使用しています。

標準のLogよりも記述が簡潔で、ビルドタイプごとにログ出力を制御できる点が便利です。

実装予定の機能一覧

機能内容CRUD対応備考
習慣一覧表示今日の習慣をカード形式で一覧表示Read
習慣登録新しい習慣を登録Create
習慣編集登録済み習慣を修正Update
習慣削除不要になった習慣を削除Delete
ホーム画面習慣達成ログや統計グラフを表示Read単なる読み取りではなく「習慣データ」と「達成ログ」を組み合わせた集計処理を行い、
統計グラフや進捗率として可視化する設計を予定しています。

使用ライブラリの選定理由

Androidのモダン開発スタックを中心に選定しました。

ライブラリ役割採用理由
Jetpack ComposeUI構築宣言的UIで開発効率が高く、再利用性に優れる
RoomローカルDB型安全で、シンプルにCRUD実装が可能
Hilt依存注入ViewModelやRepositoryの管理が簡単
Navigation Compose画面遷移管理ComposeネイティブなナビゲーションAPI
Coroutines / Flow非同期処理データフローをUIと安全に接続できる
Timberロギングログ出力がわかりやすく、軽量
Compose Material Dialogs(Datetime)日付選択ダイアログDateRangePicker実装用に採用。Compose対応で実装量が少なく、UIカスタマイズは微妙だが、安易に実装可能。

全体として、Google推奨のモダンAndroid開発スタックをベースにしつつ、UIと状態をCompose中心で完結できる構成にしています。

外部ライブラリも最小限に抑え、個人開発でも長期的にメンテナンスしやすいプロジェクト構成を意識しました。

バージョン管理とライブラリ定義

プロジェクトでは **Version Catalog(libs.versions.toml)**を導入しました。

ライブラリのバージョンを一元管理することで、アップデートや依存関係の整理を容易にしました。

プロジェクトセットアップ

プロジェクトでは**Version Catalog(libs.versions.toml)**を導入しました。

ライブラリのバージョンを一元管理することで、アップデートや依存関係の整理を容易にしました。

[versions]
kotlin = "2.2.20"
composeBom = "2025.09.00"
room = "2.8.0"
hilt = "2.57.1"
navigation = "2.9.4"
coroutines = "1.10.2"
timber = "5.0.1"
material3 = "1.3.2"

今後の流れ

次回は、実際のデータ構造(RoomエンティティやDAO)の設計と、習慣データを管理するRepository層の実装を紹介します。

まとめ

今回の記事では、習慣トラッカーアプリの設計思想と、開発を支える技術スタックについてまとめました。 個人開発とはいえ、後からの機能追加やリファクタリングを見据え、MVVM × Hilt × Room × Compose というモダン構成を採用しています。

実際に開発を進めてみると、「UI・状態・データをしっかり分離することの重要性」をあらためて実感しました。 特に Composeの宣言的UIは、状態の変化がそのまま画面に反映されるため、実装をシンプルに保ちながらも動作確認がしやすく、開発もどんどん進みました。

次回は、今回紹介した構成の中でも中核となる RoomエンティティとRepository層 の実装について紹介します。 実際に「習慣データをどのように保存・取得し、UIへ流すのか」を具体的に掘り下げながら、 アプリの“動く土台を作成予定です。

タイトルとURLをコピーしました