UI層の責務を分割するためのパターン群。レイヤードアーキテクチャ等 が「アプリ全体」の層分けなのに対し、 これらは主に プレゼンテーション層内部 の分割に関するパターン。
MVC(Model-View-Controller)¶
Model:データとビジネスロジック
View:Modelの状態を表示する
Controller:ユーザー入力を受け取り、Modelを更新する
古典的なMVC(Smalltalk由来)ではViewがModelの変更を直接観測する(Observerパターン) が、Ruby on RailsなどWebフレームワークの「MVC」はControllerがViewの描画までまとめて担うことが多く、 原義とは形が異なる点に注意。
MVP(Model-View-Presenter)¶
MVCの発展形。ViewはModelを直接参照せず、すべてPresenterを経由する。ViewはUIの表示に徹する「受け身」な存在になり、 Presenterがテスト可能なロジックを持つため、ユニットテストが書きやすくなる。
View:UIの表示のみ。Presenterからの指示で更新される(受動的)
Presenter:Viewからの入力を受け、Modelとやり取りし、Viewの更新指示を出す
Model:MVCと同様
MVVM(Model-View-ViewModel)¶
View:UIの表示。ViewModelとデータバインディングで同期する
ViewModel:Viewが必要とする状態と操作を公開する。Viewへの参照は持たない
Model:MVCと同様
MVPとの違いは、ViewとViewModelの同期を データバインディング という仕組みが自動で行う点。Presenterのように 明示的にViewを更新するコードを書かずに済む。WPF/Vue/Angularのようなバインディング機構を持つフレームワーク、 Reactの状態管理(フックやストア)もこの発想に近い。
View <---- データバインディング ----> ViewModel ----> Model
(表示に徹する) (状態とコマンドを公開)使い分け¶
サーバーサイドでリクエスト単位に処理が完結するWebアプリ:MVC(Rails, Django, Laravelなど)
テスト容易性を重視したいネイティブアプリ:MVP
リッチなデータバインディングを持つフロントエンドフレームワーク:MVVM(またはそれに準じた状態管理)
いずれも「Viewをできるだけ薄く保ち、ロジックをテストしやすい場所に追い出す」という同じ目的を持つ。