LASSIC Media らしくメディア

2026.10.06 らしくコラム

MVCとMVVMの違い、MVPも含めた画面の責務の分け方

監修・編集責任者:牛尾 昭昌(株式会社LASSIC 執行役員)

紙に鉛筆でスマホ画面のワイヤーフレームを2枚描き、その横に鉛筆を1本置いた状態を上から写した白黒の写真。

この記事の結論

  • MVCとMVVMの違いは、入力を受ける役と、画面に出す値や状態を持つ役をどこに置くかにあります。
  • MVVMはデータバインディングを前提にし、ViewModelが画面の部品を知らないので、画面なしで単体テストできます。
  • どれを選ぶかは、使う画面の仕組みにバインディングがあるかと、画面の状態の多さで決めます。

※ 本記事は2026年10月時点の公式情報(省庁・公的機関、および製品やサービスを提供する事業者が公開している資料)に基づきます。

MVCとMVVMの違いは、利用者の入力と画面の表示を、どの部品がつなぐかにあります。MVC(Model-View-Controller)では、入力をControllerが受けてModelを変え、ViewがModelの変化を受けて描き直します。MVVM(Model-View-ViewModel)では、画面に出す値と操作をViewModelにまとめ、Viewはデータバインディングでその値に結び付くだけにします。

本記事では、MVCの原典とMVVMの最初の解説をもとに両者の仕組みを整理し、MVPとの違い、同じ画面を書き分けたコード、使いどころと落とし穴をまとめます。

MVCとMVVMの違いとは

どちらのパターンも、業務のデータと処理をModelに置き、画面の部品から切り離すところは同じです。MVCは画面の側を、表示するViewと入力を受けるControllerに分けます。MVVMは、入力の受け口を画面の部品にまかせ、そのかわりに「画面のためのModel」であるViewModelを置きます。

MVC・MVP・MVVMの比べ方
項目 MVC MVP MVVM
よく参照される文書 1979年、Xerox PARCでのReenskaug氏のメモ 1996年、TaligentのPotel氏の論文 2005年、MicrosoftのGossman氏のブログ
入力を受けるもの Controller 画面の部品が受け、Presenterへ渡す 画面の部品が受け、ViewModelのコマンドを呼ぶ
表示の更新 ViewがModelの変化を受けて描き直す Modelの変化を受けて描き直す。Presenterが画面を直接操作する流派もある データバインディングでViewModelの値を画面に映す
選択中の行や編集中かどうか Viewのクラスが持つことが多い PresenterかViewが持つ ViewModelが持つ
前提になる仕組み 変更の通知 変更の通知、またはPresenterから画面への指示 データバインディング

名前が同じでも、中身が同じとは限りません。Martin Fowler氏は、MVCを画面開発で最も広く引用され、最も誤って引用されるパターンだと述べています。*9 原典のMVCとAppleのCocoaのMVCでも、Controllerの役目は違います。議論の前に、どの意味で使っているかをそろえておきます。

MVCの仕組み

MVCは、Trygve Reenskaug氏がXerox PARCに滞在していた1978〜79年に書いたメモに始まります。同氏の公開ページによると、最初の名前はModel-View-Editorでした。*2 目的は利用者の頭の中の捉え方とコンピューターの中のデータのずれを埋めることで、同じデータを別の見方で同時に見たいときに役立つ構造だとされています。

1979年12月10日付のメモでは、3つの役がこう定義されています。*1 Modelは知識を表します。Viewは表示のためのフィルターです。ViewはModelに問い合わせて表示に要るデータを受け取ります。Controllerは利用者とシステムをつなぐ役で、入力を受け取り、適切なメッセージに翻訳してViewに渡します。メモは、Viewはマウスの操作やキー入力のような利用者の入力を知るべきではない、とも書いています。

AppleのCocoaの文書が説明するMVCは、これと少し違います。*3 Controllerは1つ以上のViewと1つ以上のModelのあいだを取り持つ仲介役で、Modelが変わるとControllerに通知し、ControllerがViewを更新します。Modelは、理想的にはViewと直接のつながりを持ちません。なお、この文書は最新の推奨ではない可能性があるアーカイブ文書です。

MVC(原典)、MVC(Cocoa)、MVP、MVVMの4つの形を並べた図。原典のMVCでは利用者の入力をControllerが受けてViewに伝え、ViewがModelに問い合わせて描き直す。CocoaのMVCではControllerがViewとModelのあいだを両方向で仲介する。MVPでは画面の部品が受けた入力をPresenterに渡し、PresenterがModelを変える。MVVMではViewがデータバインディングでViewModelの値に結び付き、ViewModelだけがModelを扱う。

図のとおり、原典ではViewがModelを直接見て描き直すのに対し、CocoaではControllerが両方向を仲介します。どちらでも、画面の状態(選択中の行など)をどこに持つかは決まっていません。この空いた置き場を埋めたのが、次に見るMVVMです。

MVVMの仕組み

MVVMは、MicrosoftのJohn Gossman氏が2005年10月にブログで紹介したパターンです。*4 同氏はMVVMをMVCの変形と位置づけ、画面を開発者ではなくデザイナーが、HTMLやXAMLのような宣言的な書き方で作る環境向けだと説明しています。そして、MVVMはデータバインディングの一般的な仕組みを前提にします。Controllerの役目は、入力を受け持つ画面の部品の陰に退いたと書いています。

ViewModelという名前は「Viewのモデル」を意味します。Modelの型を画面の型に変える変換と、ViewがModelを操作するためのコマンドを持ち、選択中の項目や表示モードのような画面の状態の置き場にもなります。Modelをそのまま画面に結び付けられるのは一部だけなので、残りを受け持つ役が要る、という考え方です。

Microsoft Learnの.NET MAUIの解説は、部品どうしの関係を次のように整理しています。*5 ViewはViewModelを知り、ViewModelはModelを知りますが、ModelはViewModelを知らず、ViewModelはViewを知りません。ViewModelはINotifyPropertyChangedを実装して値の変更を画面に通知し、ボタンのような操作はICommandのプロパティにバインドします。ボタンを押せるかどうかも、画面側のコードで切り替えずにViewModelのプロパティへバインドする形が勧められています。

こうした決まった書き方は、ライブラリで省けます。.NETではCommunityToolkit.Mvvmが、変更通知の基底クラスObservableObjectやRelayCommandを提供しており、特定の画面の仕組みに依存しない作りになっています。*6

MVPとの違い

MVP(Model-View-Presenter)は、IBMの子会社だったTaligentのMike Potel氏が1996年の論文でまとめた形です。*7 論文はMVPをSmalltalkのMVCの一般化と位置づけ、データ(Model)、データのどこを指すか(選択)、どう変えるか(コマンド)、入力をどう変更に結び付けるか(インタラクター)を分けます。これらをまとめて動かす役がPresenterです。

Fowler氏の整理では、MVPのViewは部品の集まりで、部品が受けた入力はそのままPresenterに渡されます。*9 Presenterが画面の部品をどこまで操作するかには幅があり、単純な表示はViewにまかせる形をSupervising Controller、部品の操作をすべてPresenterが行う形をPassive Viewと呼んでいます。Passive Viewは、テストのしやすさを探るなかで後から生まれた形です。

MVVMとの大きな違いは、画面への反映の仕方です。MVPのPresenterは画面に指示を出せますが、MVVMのViewModelは画面を知らず、値を公開するだけです。バインディングの仕組みが無い環境で画面の処理をテストしたいならMVP、仕組みがあるならMVVMが合います。

具体例:同じ画面を書き分ける

単価1,200円の商品で、数量を入れると合計金額を出し、数量が1以上のときだけ注文ボタンを押せるようにする画面を、JavaScriptで書き分けてみます。画面の部品の代わりに、値を書き込むだけのオブジェクトscreenを使います。まずはMVCです。

// MVC:Controllerが入力を受けてModelを変え、ViewはModelを見て描き直す
class OrderModel {
  constructor(price) { this.price = price; this.qty = 0; this.listeners = []; }
  setQty(n) { this.qty = n; this.listeners.forEach(f => f()); }
  total() { return this.price * this.qty; }
}
class OrderView {
  constructor(model, screen) {
    this.model = model; this.screen = screen;
    model.listeners.push(() => this.render());   // Modelの変更を購読
  }
  render() {
    this.screen.totalText = `合計 ${this.model.total()} 円`;
    this.screen.orderEnabled = this.model.qty > 0;
  }
}
class OrderController {
  constructor(model) { this.model = model; }
  onQtyInput(text) { this.model.setQty(Number(text) || 0); }
}

ViewはModelの変更を購読し、変わるたびに合計と注文ボタンの状態を書き直します。数量が0かどうかで注文ボタンを切り替える判断は、Viewの中にあります。同じ処理をMVVMで書くと次のようになります。

// MVVM:ViewModelが画面の状態を持ち、Viewはバインドするだけ
class OrderViewModel {
  constructor(model) { this.model = model; this.subs = []; }
  set qty(text) { this.model.qty = Number(text) || 0; this.notify(); }
  get totalText() { return `合計 ${this.model.price * this.model.qty} 円`; }
  get canOrder() { return this.model.qty > 0; }
  notify() { this.subs.forEach(f => f()); }        // 変更通知
}
// 汎用のバインド処理(WPFのBindingやComposeの状態収集に当たる部分)
function bind(vm, screen) {
  vm.subs.push(() => {
    screen.totalText = vm.totalText;
    screen.orderEnabled = vm.canOrder;
  });
  screen.onQtyInput = text => { vm.qty = text; };
}

ViewModelは合計の文言と注文できるかどうかを値として公開し、画面の部品には触れません。bind関数は、WPFなどでは仕組みが肩代わりする部分です。Node.js v24で動かすと、どちらも数量3で「合計 3600 円」と注文可、空欄で「合計 0 円」と注文不可になりました。違いが表に出るのはテストです。

const { OrderViewModel } = require('./mvvm.js');
// 画面の部品を用意せずに、ViewModelだけを確かめる
const assert = require('node:assert');
const vm = new OrderViewModel({ price: 1200, qty: 0 });
vm.qty = '3';
assert.strictEqual(vm.totalText, '合計 3600 円');
assert.strictEqual(vm.canOrder, true);
vm.qty = 'abc';                                    // 数字でない入力
assert.strictEqual(vm.canOrder, false);
console.log('ok');

MVVMでは、画面の部品を用意しなくてもViewModelだけで表示の内容を確かめられます。MVCの例で同じことを確かめるには、ViewとModelを組み合わせて画面の代わりを用意する必要があります。

使いどころ

MVVMが向くのは、画面の仕組みがデータバインディングを持っている場合です。WPFや.NET MAUIのXAML、Jetpack Composeがこれに当たります。Android Developersは、ViewModelを画面単位の状態の持ち主と位置づけ、画面を回転させても状態を保てる点を主な利点としています。*8 AndroidのView方式からの移行は「Android View方式からJetpack Composeへの移行」で扱っています。

MVCが向くのは、画面の状態が少なく、入力と表示の対応が単純な場合です。Appleは、Cocoaの多くの技術がMVCを土台にしており、開発者が作るオブジェクトにもMVCのいずれかの役を求めると説明しています。*3 SwiftUIへの切り替えを考える場合は「UIKitからSwiftUIへの移行」も参考になります。

迷ったときは、3つの点で選びます。1つ目は、使う画面の仕組みにバインディングがあるかです。2つ目は、選択中の行や編集中かどうかといった画面の状態が多いかです。3つ目は、画面を作る人と処理を書く人が分かれているかです。

つまずきやすい点

1つ目は、ViewModelが画面の部品を参照してしまうことです。Microsoft Learnは、ViewModelからButtonやListViewのような画面の型を参照しないよう求めています。*5 Android DevelopersもContextやResourcesの参照を持たせないよう求めています。ViewModelは画面より長く生きることがあり、メモリリークの原因になるためです。*8

2つ目は、ViewModelがなんでも入れる箱になることです。Android Developersは、ViewModelを画面単位の状態の持ち主として使い、フォームのような再利用する部品の状態には使わないこと、ViewModelをほかのクラスや部品に渡さないことを勧めています。*8 業務のルールはModelに置き、ViewModelには画面に出す形への変換と画面の状態だけを置く、と線を引いておきます。

3つ目は、変更通知の漏れです。バインディングは通知が来て初めて画面を描き直します。Microsoft Learnは、公開しているプロパティの値が変わったらそのつどPropertyChangedを発生させ、画面の作りを理由に省かないよう書いています。*5 通知の漏れは見つけにくいので、ViewModelの単体テストで通知の発生まで確かめておきます。

委託するときの確認点

画面の開発を外部に委託するときは、まずパターンの名前ではなく中身を文書で合わせます。入力はどこで受けるか、画面の状態はどこに持つか、ViewModelやPresenterが画面の部品に触れてよいか、の3点を決めておくと、担当者が替わっても作りがぶれにくくなります。

次に、テストの範囲を決めます。MVVMやPassive ViewのMVPを選ぶなら、ViewModelやPresenterの単体テストを納品の条件に入れられます。既存のアプリで状態の持ち方が散らばっている場合の進め方は「アプリ状態管理リファクタリングを外注する進め方」で扱っています。

まとめ:MVCとMVVMで確かめておきたい3つの点

MVCとMVVMの違いを実務に生かすうえで、確かめておきたい点は3つです。第一に、入力を受ける役と画面の状態を持つ役の置き場を、名前ではなく中身で決めて文書に残すこと。第二に、MVVMを選ぶならViewModelから画面の部品やContextを参照せず、変更通知を漏らさないこと。第三に、表示の内容はViewModelやPresenterの単体テストで確かめることです。

LASSICに相談するメリット

LASSICは、元請(プライムベンダー)としてシステムの開発と保守・運用を受託しています。画面の責務分担は、.NETならWPFや.NET MAUIとCommunityToolkit.Mvvm、AndroidならJetpackのViewModelとKotlinのStateFlow、Jetpack Composeを使って組み立てます。設計では、画面の状態をどのViewModelに持たせるか、入力の検証をViewModelとModelのどちらに置くかを決めます。検証では、xUnitやJUnitでViewModelの単体テストを書き、画面を通すテストはEspressoやXCUITestで主な操作に絞り、GitHub ActionsなどのCIでプルリクエストごとに流します。

よくある質問

MVCとMVVMはどちらが優れていますか

優劣ではなく、前提の違いです。MVVMはデータバインディングの仕組みを前提にしているため、それが無い環境ではMVCやMVPのほうが素直に書けます。

MVVMのViewModelはMVCのControllerと同じものですか

同じではありません。原典のControllerは利用者の入力を受ける役ですが、ViewModelは入力の受け口を画面の部品にまかせ、画面に出す値と状態、操作のコマンドを持つ役です。

MVVMには専用のライブラリが必要ですか

必須ではありません。Microsoft Learnも、MVVMのフレームワークは使わなくてもよいが、開発を速め書き方をそろえる助けになると説明しています。

アプリの画面設計と開発のご相談

元請(プライムベンダー)として、画面の責務分担の設計から実装、テストの自動化、保守・運用までご提案します。

Remoguとリラシクなら、アプリの画面設計やリファクタリングに加わるITエンジニアも探せます。

Remoguは、リモート前提で全国から即戦力のITプロ人材を調達するサービスです。リラシクは、扱う求人がすべてリモートワークのITエンジニア専門転職エージェントです。どちらもLASSICが運営しています。

無料相談はこちら

出典

  1. *1 参考:Trygve Reenskaug「MODELS – VIEWS – CONTROLLERS」(1979年12月10日)(https://folk.universitetetioslo.no/trygver/1979/mvc-2/1979-12-MVC.pdf)。出典:Model・View・Controller・Editorの定義を参照(原典のメモ)(2026年10月確認)
  2. *2 参考:Trygve Reenskaug「MVC XEROX PARC 1978-79」(著者の公開ページ)(https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html)。出典:名称の変遷(Model-View-EditorからModel-View-Controllerへ)とMVCの目的を参照(2026年10月確認)
  3. *3 参考:Apple「Model-View-Controller」(Cocoa Core Competencies、Documentation Archive、2018年4月6日更新)(https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html)。出典:Model・View・Controllerの各オブジェクトと相互のやり取りを参照(Retired Document)(2026年10月確認)
  4. *4 参考:John Gossman「Introduction to Model/View/ViewModel pattern for building WPF apps」(Microsoft Learn アーカイブ、2005年10月8日)(https://learn.microsoft.com/en-us/archive/blogs/johngossman/introduction-to-modelviewviewmodel-pattern-for-building-wpf-apps)。出典:MVVMの位置づけ、View・Model・ViewModelの役割、データバインディングを参照(2026年10月確認)
  5. *5 参考:Microsoft Learn「Model-View-ViewModel」(Enterprise Application Patterns Using .NET MAUI)(https://learn.microsoft.com/en-us/dotnet/architecture/maui/mvvm)。出典:View・ViewModel・Modelの関係、INotifyPropertyChanged、ICommand、単体テスト、MVVMフレームワークを参照(2026年10月確認)
  6. *6 参考:Microsoft Learn「Introduction to the MVVM Toolkit」(.NET Community Toolkit)(https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/)。出典:CommunityToolkit.Mvvmの対象環境と提供する型(ObservableObject、RelayCommand)を参照(2026年10月確認)
  7. *7 参考:Mike Potel「MVP: Model-View-Presenter The Taligent Programming Model for C++ and Java」(Taligent、1996年)(https://www.wildcrest.com/Potel/Portfolio/mvp.pdf)。出典:MVPの成り立ち、選択・コマンド・インタラクター・Presenterの説明を参照(2026年10月確認)
  8. *8 参考:Android Developers「ViewModel overview」(https://developer.android.com/topic/libraries/architecture/viewmodel)。出典:ViewModelの位置づけと利点、Best practicesを参照(2026年10月確認)
  9. *9 参考:Martin Fowler「GUI Architectures」(martinfowler.com、2006年7月18日)(https://martinfowler.com/eaaDev/uiArchs.html)。出典:Model View Controller、Model-View-Presenter(Supervising Controller、Passive View)を参照。解説記事のため補助として参照(2026年10月確認)




View