
みなさまこんにちは〜!
メモリアインクのすだです。
本日は、
Androidアプリ開発における「MVVM」と呼ばれるアーキテクチャの基本について、実際のコードを用いて解説していきます!
この記事を読んでわかること…
・MVVMというアーキテクチャについて
・MVVMでの実装方法
MVPアーキテクチャに関しては、以下の記事で詳細に記載しています。
ぜひ合わせてご覧ください!


環境
- Kotlin (ver 1.9.0)
- Android Studio (Giraffe | 2022.3.1 Patch 3)
MVVMとは?
MVVM(Model-View-ViewModel)は、Androidアプリ開発でGoogleが推奨している設計パターンです。
UI(画面)とロジック(処理)をきれいに分離し、保守性・テスト性の高いアプリを作ることができます。
MVVMの3つの役割
①Model(モデル)
アプリ内のデータ処理やビジネスロジックを担当します。(API通信, DB, Repository)
②ViewModel(ビューモデル)
UIの状態やロジックを保持。非同期処理もここで行います。(ViewModel, LiveData, Flow)
③View(ビュー)
UIの描画とイベント受け取りを担当します。(xml, Activity, Fragment, Compose)
(ViewModelのデータを監視して表示を更新する)


MVVMを採用するメリット
UIとロジックをしっかり分けられる(責任の分離)
UIとロジックを分離することは、処理の流れを追いやすく、メンテナンスしやすいといったメリットを持ちます。
また、Androidでは、ActivityやFragmentは画面回転やバックグラウンド遷移のたびにライフサイクルが再生成されます。
このとき、UIの初期化だけでなく、API通信や画像読み込みなどの重い処理も再実行されてしまうと、メモリ使用量が増え、最悪の場合はアプリのクラッシュやパフォーマンス劣化を招く可能性があります。
MVVMにおいては、ViewModelがライフサイクルをまたいで状態を保持できるため、こうした問題を回避する助けになります。
非同期処理や状態管理が簡単にできる
JetpackのLiveDataやKotlinのStateFlowを使って、ViewModelからViewへ自動でUI更新ができます。
ViewModelが値を更新すると、Viewが自動で追従して表示を変えてくれる=バインディングのような挙動が実現可能です。
テストがしやすくなる(=品質向上)
ViewModelは、UIに依存しない純粋なクラスです。
そのため、JUnitなどでロジックを単体テストしやすいのが大きな利点です。
MVVMやMVPが「UIの構造に関する設計パターン」であるのに対し、
クリーンアーキテクチャは「アプリ全体の依存関係と責務分離のための原則」ということになります。
MVPやクリーンアーキテクチャの設計については以下の記事で詳細を説明しておりますので、ぜひ合わせてご覧ください!↓




サンプル処理で学ぶMVVM実装
それでは、MVVMアーキテクチャを採用して「画面にあるボタンを押下するとメッセージがトースト表示される」という簡単な処理を 以下の構成で作ってみます。
├─ MainActivity.kt ← View(UI表示)
├─ MainViewModel.kt ← ViewModel(ロジック)
├─ MessageModel.kt ← Modelインターフェース
└─ MessageModelImpl.kt ← Model実装
前提理解①:
インターフェース(interface
)とは?
「何ができるか(振る舞い・機能)」を約束するだけの設計図です。
中身(実装)は書かず、どんな関数を持つべきかだけを定義します。
前提理解②:
クラス(class
)とは?
具体的な設計と中身(処理)が入った部品です。
変数や関数を持ち、実際の振る舞いやデータを定義できます。
View
Activityの実装
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// ViewModelの生成(今回は簡易的にModelを直接注入)
viewModel = MainViewModel(MessageModelImpl())
val button = findViewById<Button>(R.id.button)
// ボタン押下 → ViewModelへ通知
button.setOnClickListener {
viewModel.onButtonClicked()
}
// LiveDataを監視して、変化があればトースト表示
viewModel.toastMessage.observe(this) { message ->
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
}
}
↑ここでユーザーのアクションをクリックリスナーで検知し、ボタン押下後の処理をViewModelに委ねます。
LiveData(ViewModel)を監視して、「データの変更があれば行う処理」を記述します。
ViewModel
ViewModelの実装
class MainViewModel(
private val model: MessageModel
) : ViewModel() {
// LiveDataでViewへ状態通知
private val _toastMessage = MutableLiveData<String>()
val toastMessage: LiveData<String> get() = _toastMessage
fun onButtonClicked() {
val message = model.getMessage()
_toastMessage.value = message
}
}
↑ViewModelはUIの状態(トーストメッセージ)をLiveDataで持ちます。
ボタンが押されたらModelからデータを取得し、Viewに通知します。
Model
インターフェイスの実装
// データの取得や処理を定義
interface MessageModel {
fun getMessage(): String
}
Modelの実装
// 実際のデータ処理の中身
class MessageModelImpl : MessageModel {
override fun getMessage(): String {
return "こんにちは!"
}
}
↑今回はただ文字列を返しているだけですが、他にも以下のような処理を行います。
・Web APIとの通信(Retrofitなど)
・データベースの読み書き(Roomなど)
・ファイルアクセス
・データ加工や整形
・キャッシュ処理 など
まとめ
おつかれさまでした。いかがでしたでしょうか!
MVVMはAndroidに最適な設計パターンで、公式にも推奨されています。
開発を始めたての方には少し難しく感じるかもしれませんが、慣れてしまえば柔軟に実装していけるかと思いますので、ぜひ勉強してくださいね!



技術者としてのキャリアパスを次のレベルへと進めたい皆様、
<未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】>
自分の市場価値をさらに向上させてみませんか?
それではまた次回の記事でお会いしましょう!
コメント