この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: MVC
SEOタイトル: MVC アーキテクチャ完全ガイド

この記事の要点
  • MVC = Model / View / Controller の 3 層分離アーキテクチャ
  • Model: データ / ビジネスロジック、View: UI / 表示、Controller: 入力処理 / 仲介
  • 起源は Smalltalk-80 (1979)、Trygve Reenskaug が GUI 設計用に提案
  • Web 系: Ruby on Rails / Laravel / Spring MVC / Django / ASP.NET MVC が代表
  • 派生: MVP / MVVM / MVI。SPA 時代は API + フロントが MVVM / Flux 系を採用

MVC とは

MVC (Model-View-Controller) はアプリケーションを 3 つの責務に分割するアーキテクチャパターンです。1979 年に Trygve Reenskaug が Smalltalk-80 のために考案し、その後 GUI アプリ・Web アプリの基本設計として広く普及しました。

役割責務
Modelデータ構造、永続化、ビジネスルールEloquent モデル、JPA エンティティ、Active Record
View表示、UI レンダリングBlade / Thymeleaf / JSP / HTML テンプレート
Controller入力受付、Model 操作、View 選択Laravel Controller、Spring @Controller

情報の流れ (Web MVC の典型)

[ブラウザ]
   ↓ HTTP リクエスト (例: GET /users/1)
[ルーター]
   ↓
[Controller]  ← ① 入力を受け取る
   ↓ Model に問い合わせ
[Model]       ← ② DB アクセス / ロジック
   ↑ データを返す
[Controller]  ← ③ View を選んでデータを渡す
   ↓
[View]        ← ④ HTML をレンダリング
   ↓ HTTP レスポンス
[ブラウザ]

各層の責務 (詳細)

Model の責務

  • データの永続化(DB アクセス)
  • ビジネスロジック / ドメインルール
  • バリデーション(ドメインレベル)
  • 状態を持つ(インスタンス変数)
  • View や Controller を知らない(依存方向: Controller → Model)

View の責務

  • 受け取ったデータを HTML / JSON / その他形式に整形
  • 表示専用のロジック(フォーマット、ループ、条件分岐)
  • ビジネスロジックを書かない(プレゼンテーションロジックのみ)
  • Model に直接アクセスしない(Controller 経由で受け取る)

Controller の責務

  • HTTP リクエストを受け取る
  • 必要に応じて Model を呼び出す
  • 結果を View に渡す
  • ロジックを書きすぎない(Fat Controller アンチパターン)

Laravel での MVC 実装例

// Model: app/Models/User.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $fillable = ['name', 'email'];

    // ドメインメソッド
    public function isAdmin(): bool
    {
        return $this->role === 'admin';
    }
}

// Controller: app/Http/Controllers/UserController.php
namespace App\Http\Controllers;

class UserController extends Controller
{
    public function show(int $id)
    {
        // ① Model からデータ取得
        $user = User::findOrFail($id);

        // ② View を選んで渡す
        return view('users.show', ['user' => $user]);
    }
}

// View: resources/views/users/show.blade.php



    

{{ $user->name }}

{{ $user->email }}

@if ($user->isAdmin()) 管理者 @endif

MVC が選ばれる代表的フレームワーク

言語フレームワーク登場年
RubyRuby on Rails2004
PHPLaravel / CodeIgniter / Symfony / CakePHP2011 / 2006 / 2005 / 2005
PythonDjango (MTV) / Flask2005
JavaSpring MVC / Struts / Play2003 / 2000
C#ASP.NET MVC / ASP.NET Core MVC2009
Node.jsExpress + 自前 MVC / NestJS / Adonis2010〜

Django は厳密には MTV (Model-Template-View) を名乗りますが、Template=View、View=Controller と読み替えれば MVC と同じです。

MVC の派生パターン

パターン特徴主な用途
MVCController が View を選ぶサーバ Web アプリ
MVP (Presenter)Presenter が View ↔ Model を仲介、View は受動Android (古典) / WinForms
MVVM (ViewModel)双方向データバインディングで自動同期WPF / Vue / Knockout / SwiftUI
MVI (Intent)単方向データフロー、状態を一元管理Redux / Flux / Compose
Clean / Onion依存方向を内側へ統一、層を増やす大規模 Enterprise

現代の MVC: API + SPA への分離

近年はサーバが MVC でレンダリングする形より、サーバは JSON API、フロントは Vue/React/Angular で MVVM の構成が主流です:

[ブラウザ (React/Vue)]
   ├ View (コンポーネント)
   └ ViewModel (state / store)
        ↑↓ JSON
[サーバ (Laravel/Spring)]
   ├ Controller (API エンドポイント)
   ├ Service (ビジネスロジック)
   └ Model (DB アクセス)
        ↑↓
[DB]

Fat Controller アンチパターン

Controller にビジネスロジックを書きすぎると、テスト困難・再利用不能・肥大化します。Service 層UseCaseに切り出します:

// ❌ Fat Controller
class OrderController extends Controller
{
    public function store(Request $request)
    {
        // 200 行のロジック...
        DB::beginTransaction();
        $order = Order::create($request->only('items'));
        foreach ($order->items as $item) {
            $stock = Stock::find($item->product_id);
            $stock->qty -= $item->qty;
            $stock->save();
        }
        Mail::to($order->user)->send(new OrderCompleted($order));
        // ...
    }
}

// ✅ Service 層へ分離
class OrderController extends Controller
{
    public function __construct(private OrderService $service) {}

    public function store(StoreOrderRequest $request)
    {
        $order = $this->service->place($request->validated());
        return redirect()->route('orders.show', $order);
    }
}

class OrderService
{
    public function place(array $data): Order
    {
        return DB::transaction(function () use ($data) {
            $order = Order::create($data);
            $this->reserveStock($order);
            event(new OrderPlaced($order));
            return $order;
        });
    }
}

MVC のメリット・デメリット

メリットデメリット
関心の分離で保守性が向上規模が小さいと過剰設計
並行開発しやすい(View 担当、Model 担当)3 層境界の判断に学習コスト
テスタビリティ(Model 単体テスト可)Fat Controller / Fat Model に陥りやすい
フレームワーク化で標準化SPA 時代は Controller / View の境界が薄い

FAQ

Q: MVC と MVP の最大の違いは?
A: MVC では View が Model を直接参照するケースがありますが、MVP では View は完全に受動で Presenter 経由でしか Model に触れません。

Q: SPA (React/Vue) では MVC は古い?
A: クライアント側は MVVM / Flux が主流。ただしサーバ側 API は依然として MVC が一般的です。「両側でアーキテクチャが違う」が現代の標準です。

Q: 小さなツールでも MVC を守るべき?
A: 小さければ 1 ファイルでも十分。チーム開発や 1000 行を超え始めたら層分離で得をします。