MVC
Model-View-Controller
概要(サマリー)
MVC(Model-View-Controller)とは、システム開発(プログラムの設計)において、コードの役割を「Model(データ担当)」「View(画面担当)」「Controller(交通整理担当)」の3つに分割して整理する設計パターン(アーキテクチャ)である。
「レストランの役割分担」にたとえられる。厨房で料理を作るシェフ(Model)、お皿に綺麗に盛り付けられた料理(View)、お客様から注文を聞いてシェフに伝え、料理を運ぶウェイター(Controller)のように、それぞれの得意分野に処理を分割することで、複雑なプログラムでも整理整頓され、修正や追加が簡単に行えるようになる。
詳細解説
MVCとは何か
何でも1枚のファイルにプログラムを書き込んでいくと、機能が増えるにつれて「画面のデザインを変えたいだけなのに、関係ないデータベースのコードまで壊してしまった」といったミスが発生する。
これを防ぐため、機能ごとにコードをきれいに切り分けようというルールがMVCである。多くのWebシステム開発用フレームワーク(Ruby on Rails, Laravel, Djangoなど)の基本設計として採用されている。
各要素の具体的な役割
- Model(モデル) — データとビジネスロジック担当:
データベースとのやり取り、データの計算、入力チェックなど、「システムの裏側の頭脳・ルール」にあたる部分。画面の見た目(デザイン)については一切関与しない。 - View(ビュー) — 画面表示担当:
ユーザーの画面に見えるHTMLやCSS、画面デザインの出力部分。Modelから渡されたデータを受け取って、綺麗に整えて画面に映し出す。データの書き換えルールなどは一切持たない。 - Controller(コントローラー) — 交通整理・仲介担当:
ユーザーからのクリックや文字入力を最初に受け取る窓口。ユーザーからの要求に応じて、「Modelからデータを取ってきて」「それをViewに渡して画面を作って」と命令を出し、二者を橋渡しする。
MVCを意識した簡単なプログラムのイメージ
以下は、JavaScriptを用いてMVCの役割分担をシンプルに表現した、概念的なコード例である。
// 1. Model: ユーザーデータの管理を担当
class UserModel {
constructor() {
this.users = [{ id: 1, name: "たろう" }];
}
// データベースからユーザーを探すロジック
getUserById(id) {
return this.users.find(user => user.id === id);
}
}
// 2. View: 画面の表示(HTMLの生成)を担当
class UserView {
render(user) {
if (!user) {
return "<h1>ユーザーが見つかりません</h1>";
}
return `<h1>こんにちは、${user.name}さん!</h1>`;
}
}
// 3. Controller: ModelとViewを仲介して動作を決定する
class UserController {
constructor(model, view) {
this.model = model;
this.view = view;
}
// ユーザーからの要求「ID:1のページを表示して」を処理する
showUserProfile(userId) {
const user = this.model.getUserById(userId); // Modelにデータを頼む
const html = this.view.render(user); // Viewに画面を作ってもらう
console.log(html); // 実際のシステムではここでブラウザにHTMLを送信する
}
}
// 実行処理
const app = new UserController(new UserModel(), new UserView());
app.showUserProfile(1); // 出力: <h1>こんにちは、たろうさん!</h1>
MVCを採用するフレームワークと、しないフレームワーク
MVCは多くのWebフレームワークの標準的な設計として採用されている。例えばRuby on Rails、Laravel(PHP)、Django(Python)、Spring(Java)などが代表的である。一方、React・Vue・Svelte などの現代のフロントエンドフレームワークは、コンポーネント指向という別の考え方を採用しており、MVCの枠組みには収まらない。AIにコードを頼む際は、使うフレームワークがMVC前提かどうかを把握した上で指示を出すと、より的確なコードが得られる。
AIコーディングとの関係
AIコーディングで新しいアプリの機能(例:「ユーザーのマイページ機能」など)を生成させる際、AIは1つのファイルや1つの関数に、デザインからデータベース接続までのすべてのロジックを詰め込んだ、メンテナンス性の低い「ぐちゃぐちゃなコード」を出力することがある。
これを防ぎ、綺麗なシステムにするためにAIへ「MVC」を意識した指示を行うと効果的である。
- MVCを指定した指示出し:
「新しい機能を実装するためのコードを、MVCパターンに基づいて、Model、View、Controllerそれぞれのファイルに分割して書いてください」と指示する。
これにより、フレームワークの流儀に沿った、人間が後から修正しやすい拡張性の高い構成でコードを生成させることができる。 - 「Fat Controller(太ったコントローラー)」の修正:
AIがコントローラーの中にデータ計算の処理を書き込みすぎた場合、「コントローラーにビジネスロジックが偏るFat Controllerになっています。ロジックをModel側に移動させ、Controllerを軽量にリファクタリングしてください」と指示することで、役割分担が正しい本来のスマートな構成に直させることができる。
よくある勘違い
MVCはWebアプリケーション専用のルール?
そうではない。
MVCは元々、1970年代にGUI(デスクトップアプリの画面表示など)のソフトウェアを開発するために考案された古い歴史を持つ設計パターンである。その後、Webブラウザからのリクエストとレスポンスを処理する構造に非常に相性が良かったため、Web業界で大流行し、Web開発の代名詞的な用語になった。
MVCのルール通りに作らないとシステムは動かない?
動く。
MVCは、あくまでも「人間が後から管理・修正しやすくするための、開発者同士の暗黙の整理ルール」である。どれほどファイルがごちゃ混ぜで、すべてのロジックが1つに固まっていても、文法が合っていればコンピュータは全く問題なく処理を実行できる。しかし、それではチーム開発や将来の修正が地獄になるため、実務ではルールを守って作ることが強く求められる。
ControllerはModelとViewの両方を「直接呼び出す」必要がある?
必ずしもそうではない。
基本的なMVCではControllerがModelとViewを橋渡しするが、ViewがModelを直接参照する実装も一部のフレームワークでは許容されている。重要なのは「誰がデータを変更する責任を持つか」という役割の分離であり、「機械的にControllerを通さなければならない」という硬いルールではない。フレームワークごとに慣例が異なるため、使用するフレームワークのドキュメントに従うのが最も確実である。
まとめ
- MVCは、コードの役割を Model(データ)、View(画面)、Controller(仲介者)の3つに切り分ける設計ルール。
- レストランに例えると、シェフ(Model)、料理(View)、ウェイター(Controller)の役割分担。
- 役割を分けることで、デザイン修正時にデータを壊すなどの事故を防ぎ、メンテナンスしやすくなる。
- AIへコード生成を頼むときは、MVCを指定して役割ごとにファイルを分割させると、クリーンな設計になる。
より詳しくAIに聞いてみよう
- Ruby on RailsやLaravelなどのWebフレームワークで、Model・View・Controllerそれぞれのファイルが配置される一般的なディレクトリ構成について教えてください。
- MVCと、そこから派生した「MVP(Model-View-Presenter)」や「MVVM(Model-View-ViewModel)」といった設計パターンの違いについて分かりやすく説明してください。
- コントローラーが処理を持ちすぎる「Fat Controller」を防ぐために、モデルをスリムに保つ「Skinny Controller, Fat Model」の考え方と実装テクニックを教えてください。
- AIコーディングアシスタントに、MVCに基づいたRails(またはLaravel)の新規機能追加用コードを一括で出力してもらうための最適なプロンプトを提示してください。
- 近年のフロントエンド開発(ReactやVueなど)において、従来のMVCに代わってコンポーネント指向や単一指向データフロー(Fluxなど)が主流になった理由を解説してください。