Flutter + Riverpod の構成は MVVM に近い
Flutterアプリを設計する際、特に、Riverpod を用いた設計では、「Controller」と名付けた状態管理クラスがMVC (Model-View-Controller) と MVVM (Model-View-ViewModel) のどちらのアーキテクチャのレイヤーに属するのか迷うことがあるでしょう。
本記事では、MVCとMVVMの違いを整理し、Flutter + Riverpod の構成がどちらに近いのかを考察します。
MVCとMVVMの基本的な定義
1. MVC (Model-View-Controller)
概要: MVCは、アプリの責務を「データの管理 (Model)」「画面表示 (View)」「ユーザー操作の処理 (Controller)」に分割するアーキテクチャです。
各レイヤーの役割
Model: アプリケーションが扱うデータやビジネスロジックを管理する。
View: UI部分。ユーザーに表示する。
Controller: ユーザー操作を受け取り、Modelを更新し、Viewに反映させる。
特徴:
Controllerがユーザー入力を処理し、Modelを更新してViewを描画する。
ViewとControllerが密接に連携するため、Controllerが肥大化しやすい。
画面(UI)が増えるとControllerの負担が大きくなり、保守が難しくなる。
2. MVVM (Model-View-ViewModel)
概要: MVVMは、ViewとModelの間に「ViewModel」を挟み、状態管理をViewModelに集約するアーキテクチャです。
各レイヤーの役割
Model: データやビジネスロジックを管理する (MVCとほぼ同じ)。
View: UI部分。ユーザーに表示する。
ViewModel: Viewに必要な状態や表示ロジックを持つ。ViewがViewModelを監視し、変更が自動で反映される。
特徴:
ViewとViewModelがリアクティブに連携し、ViewModelがModelを操作する。
UIはViewModelを監視するだけで状態を取得でき、コードの責務が整理しやすい。
画面ごとにViewModelを用意することで、Controllerが肥大化する問題を回避できる。
Flutter + Riverpod のアーキテクチャはどちらか?
FlutterでRiverpod(特に AsyncNotifier など)を用いる場合、次のようなレイヤー構成になります。
Model: エンティティやデータ管理クラス。
Controller (状態管理クラス): AsyncNotifier などで状態を管理し、UI用のデータを提供する。
Screen (UI層): Riverpodの ref.watch でControllerの状態を監視し、UIを再描画する。
この構成を見ると、Controllerが「状態の管理」と「操作」を担い、View (Screen) はそれを監視して描画を行う形になっています。
これは MVVMの構造と非常に近い です。
MVCとの違い
MVCの場合、Controller は主にユーザー操作を受け取り、直接Modelを操作する役割 を持ちますが、今回の「Controller」は 状態管理と状態提供を主な役割とし、Modelを操作する ため、実態としては「ViewModel」に近いといえます。
結論: Flutter + Riverpod の構成は MVVM に近い
名前は「Controller」としていても、
View(Screen)はControllerを監視し、
Controller(AsyncNotifier)は状態を管理し、
Model(エンティティやリポジトリ)はデータを管理する、
という構造を取るため、実際には MVVMに分類される のが自然です。
まとめ
MVC はViewとControllerの関係が強く、ControllerがModelを操作する。
MVVM はViewがViewModelを監視し、ViewModelがModelを操作する。
Flutter + Riverpod では、「Controller (AsyncNotifier)」がViewModelの役割を担うため、MVVMに近いアーキテクチャである。
「Controller」という命名にとらわれず、役割として「ViewModel」として整理するとアーキテクチャが明確になる。
Flutterでの設計を考える際、MVCとMVVMの違いを理解し、適切な責務分割を行うことで、より保守しやすいコードを書くことができます。