| この記事の要点 |
|---|
|
MVC とは
MVC (Model-View-Controller) は Web アプリケーションを 3 つの責務に分けて設計する古典的なパターンです。
| 層 | 役割 | 例 |
|---|---|---|
| Model | データとビジネスロジック | DB 接続、エンティティ、サービスクラス |
| View | 表示(プレゼンテーション) | HTML テンプレート、JSP、Blade、Twig |
| Controller | リクエスト処理と View 選択 | URL ハンドラ、@Controller クラス |
MVC のフロー
- ユーザがブラウザでリクエスト送信
- Controller がリクエストを受信
- Controller が Model を呼び出してデータ取得
- Controller が View にデータを渡す
- View が HTML を生成してレスポンス
主要フレームワーク別の実装
Spring MVC (Java)
// Controller
@Controller
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService; // ← Model 層
@GetMapping("/{id}")
public String show(@PathVariable Long id, Model model) {
User user = userService.findById(id); // Model 呼び出し
model.addAttribute("user", user);
return "users/show"; // ← View 名(Thymeleaf テンプレート)
}
}
// Model (Entity + Service)
@Entity
public class User {
@Id private Long id;
private String name;
}
@Service
public class UserService {
@Autowired private UserRepository userRepository;
public User findById(Long id) {
return userRepository.findById(id).orElseThrow();
}
}
<!-- View: resources/templates/users/show.html (Thymeleaf) -->
<h1 th:text="${user.name}">名前</h1>
<p th:text="${user.email}">メール</p>
Laravel (PHP)
// Controller: app/Http/Controllers/UserController.php
class UserController extends Controller {
public function show($id) {
$user = User::findOrFail($id); // Model (Eloquent)
return view("users.show", compact("user")); // View 呼び出し
}
}
// Model: app/Models/User.php
class User extends Model {
protected $fillable = ["name", "email"];
}
<!-- View: resources/views/users/show.blade.php -->
<h1>{{ $user->name }}</h1>
<p>{{ $user->email }}</p>
Rails (Ruby)
# Controller: app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id]) # Model
# 自動的に app/views/users/show.html.erb をレンダリング
end
end
# Model: app/models/user.rb
class User < ApplicationRecord
end
<!-- View: app/views/users/show.html.erb -->
<h1><%= @user.name %></h1>
<p><%= @user.email %></p>
MVT とは (Django)
Django は MVC のうち「View」と「Controller」の役割が逆転した独自命名を採用しています。
| 標準 MVC | Django (MVT) | 説明 |
|---|---|---|
| Model | Model | 同じ |
| View (HTML) | Template | HTML テンプレート |
| Controller | View | リクエスト処理(紛らわしい) |
Django (Python) の例
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path("users/<int:id>/", views.user_detail, name="user_detail"),
]
# views.py (役割は MVC の Controller)
from django.shortcuts import render, get_object_or_404
from .models import User
def user_detail(request, id):
user = get_object_or_404(User, pk=id) # Model 呼び出し
return render(request, "users/detail.html", {"user": user}) # Template
# models.py (Model)
from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
<!-- templates/users/detail.html (Template) -->
{% extends "base.html" %}
{% block content %}
<h1>{{ user.name }}</h1>
<p>{{ user.email }}</p>
{% endblock %}
MVC のメリット
- 責務分離: 各層が独立してテスト可能
- 並行開発: フロント (View) とバック (Controller/Model) を別チームで開発可能
- 保守性: View 変更がロジックに影響しない
- 再利用: 同じ Model を複数 View で使い回せる
- テスト容易: Model / Controller を独立して単体テスト可能
MVC の限界とモダンアーキテクチャ
純粋 MVC では Controller がビジネスロジックを抱え込む「Fat Controller」問題が起きがち。モダンな対策:
- Service 層追加: Controller → Service → Model の 4 層
- Repository 層: DB アクセスを抽象化(Model から分離)
- DTO: Controller ↔ View 間のデータ転送オブジェクト
- Form Request / DTO 検証: バリデーション層の分離
モダンな層構成例 (Spring Boot)
- Controller: HTTP 受付、リクエスト → DTO 変換
- Service: ビジネスロジック、トランザクション境界
- Repository: DB アクセス (JPA / MyBatis)
- Entity: DB マッピング
- DTO: API レスポンス / リクエスト型
SPA + API での MVC
React/Vue + REST API の構成では、View が完全にフロント側に移動:
- サーバ側: Model + Controller (Service 含む)。REST API で JSON 返却
- クライアント側: View (React/Vue コンポーネント) + 状態管理
関連記事
同階層のページ
- 環境構築とプロジェクト/アプリの作成
- MVC(MVT)のそれぞれの使い方と説明
- データベースへの接続と操作
- Django Administration
- git管理
- エラー一覧
- バージョンの確認方法
- ログ出力方法
- SQLのログ出力方法
- ログのローテート設定
- settings.pyの定数にアクセスする方法
- 本番環境へのインストールとアプリのデプロイ(apache編)
- 本番環境へのインストールとアプリのデプロイ(nginx編)
- djangoアプリの本番の開始URLを変更する
- 静的(static)ファイルの置き場所と読み込み(画像、css、js )
- CSRFトークンをAjaxで使用する方法
- ajaxの使用例(POST編)
- ファイルのアップロードとファイルの名前
- クイックスタート/チュートリアル
- ログイン機能
- テンプレート側のログイン判定
- ビュー側のログイン判定
- 管理者ユーザーの作成/判定と管理画面
- モデルのjson化とレスポンス
- runserverでポートを指定する方法
- cronによるバッチ実行
- テンプレートで利用する共通のcontextを定義する方法
- プログラムが本番サーバーで反映されない場合の対処法
- APIの作成
- cron用コマンド・ファイルの作成
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Git pushした変更の取消し|revert・履歴変更と保護の注意点 2026-10-15 23:49:01
- Gitでローカルを戻す前に|reset・restoreの違いと退避範囲 2026-10-15 23:49:01
- Git rebaseの使い方|対象範囲・競合解決・pushの判断 2026-10-15 22:50:59
- Git pullの使い方|取込み先・ff-only・競合とstashの注意点 2026-10-15 22:50:59
- Git pushの使い方|送信先・タグ・force-with-leaseの条件 2026-10-15 22:12:47
- Git remoteの設定・確認・削除|SSH URLとfetch/pushの違い 2026-10-15 22:12:47
- Gitリモートリポジトリの作成|初回push・既存履歴・mirrorの注意 2026-10-15 15:48:16
- Gitのuser.name・user.email設定|local/global・確認と過去履歴の注意 2026-10-15 15:30:07
- LinuxにGitをインストール|配布元・初期設定・TLSと認証の確認 2026-10-15 15:30:06
- Git導入と初回push|Linuxサーバー・Windows/macOS・SSH設定 2026-10-15 14:51:54
- Db2のCREATE INDEX|索引定義・INCLUDEと実行計画の確認 2026-10-15 14:10:22
- Db2の自動採番|IDENTITY・ID取得とRESTARTの注意点 2026-10-15 14:10:22
- 【DB2】特定スキーマの全テーブルの全カラム情報を取得する方法 2026-10-15 13:53:15
- Db2のシーケンスとIDENTITYの違い|採番とカタログの確認SQL 2026-10-15 13:53:15
- Db2で複数カラムをUPDATEする方法|SET・WHEREと更新前の値 2026-10-15 13:53:15