MVCとは

Model/View/Controller

MVCは、Model/View/Controllerの略で、ソフトウェア開発におけるデザインパターンの一つで、アプリケーションのコンポーネント(部品)を3つの役割に分割して設計します。

MVCの目的

MVCの主な目的は、アプリケーションのコンポーネントを分離することで、コードの保守性や拡張性を向上させることです。各コンポーネントが明確に分かれているため、複数の開発者が同時に作業して生産性を向上させます。MVCのパターンはWebアプリケーション開発で採用されています。

プログラムの複雑化

プログラムが肥大化するとさまざまなファイル修正が必要となり、致命的なバグの原因にもなります。

  • プログラムファイルの増加
  • 処理増加によるコードの長文化
  • 処理の重複

MVCで役割分担

プログラム肥大化を解決する手段としてMVCが利用されます。「Model」「View」「Controller」にファイル分担することで、開発者にわかりやすく管理しやすいプロジェクトになります。

Webフレームワーク

PHP、Ruby、Java などのプログラム言語には、さまざまなWebフレームワークがあります。

プログラム言語 フレームワーク
PHP 「Laravel」「CakePHP」など
Ruby 「RubyOnRails」
Java 「Struts」「Spring」など
Python 「Django」「Flask」など

ビジネスロジック

Webフレームワークでは、ビジネスロジックを考慮しながら設計・開発します。 ビジネスロジックとは以下の「3階層システム」のようなものあがありますが、ここでは詳しい説明を割愛します。

  • プレゼンテーション層
  • ビジネスロジック層
  • データアクセス層

Laravel のファイル構成

MVCのファイル構成はフレームワークによって若干違いますが、基本的な考え方は同じです。例えば「Laravel」では以下のようなファイル構成で「Controllers」「Models」「views」フォルダでファイルを管理します。

MVCの基本

Model(モデル)

モデル(モデル)とは

Model(モデル)はアプリケーションのデータやビジネスロジックを管理するクラスです。データの保存、取得、更新、削除などの処理を管理します。モデルは通常、データベースからのデータの取得や保存など、データ処理に関連するタスクを担当します。

実態や振る舞いなどをプログラム

Modelは、現実世界に存在する実態や振る舞いなどをプログラムとして表現する役割を担います。例えば動物モデルでは「名前」「種別」「性別」などの性質や、「歩く」や「食べる」といった振る舞いなどを抽象的にモデリングします。

モデル
public class Dog extends Animal {
    public String name;
    public String type;
    public Enum gender;

    public void walk() {

    }

    public void eat(Food something) {

    }
}

View(ビュー)

View(ビュー)は、ユーザーインターフェースを表示する役割を担当します。モデルから情報を取得して表示し、ユーザーに情報を視覚的に表示します。

WebシステムではHTMLやテキストデータ表示

画面上に表示されるテキスト、ボタン、画像などが含まれ、WebシステムではHTMLテンプレート(プログラムを含んだHTML)やJSONデータに相当します。

ビュー(Blade)
<div class="course-top">
  <div class="title">
    <h2 class="h2">
      <img src="{{ asset('images/logo/logicoya_logo_mark_wh.png') }}" width="60" class="inline">
      <span>{{ $teaching_material->no }}.</span>
      {{ $teaching_material->name }}
    </h2>
    <div class="topic_path">
      <a class="" href="{{ route('course.index') }}">
        {{ __('label.online_material') }}
      </a>
      @if (isset($course->name))
      &gt;
      <a class="" href="{{ route('course.find_by_key', ['key' => $course->key]) }}">{{ $course->name }}</a>
      @endif
    </div>
  </div>
</div>

Controller(コントローラ)

Controller(コントローラ)は、ユーザーからのリクエストに対して適切な処理をするクラスです。ボタンクリック、フォーム入力などリクエストを受け取り、データ操作や煩雑な処理は、ModeクラスやServiceクラス、表示はViewファイルで処理するようコントロールします。

コントローラー(Laravel)
<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Facades\Course;

class HomeController extends Controller
{
    public function index()
    {
        //モデルに任せる
        $auth = Auth::user();
        //ビューに任せる
        return view('home', ['auth' => $auth]);
    }

    public function personal_information()
    {
        //ビューに任せる
        return view('personal_information');
    }
}

Fat Controllerに注意

が、システムが膨大になるとコントローラー自体のコードも複雑化します。これをFat Controllerといいますが、コントローラーはシンプルな処理に専念するよう、設計方法を見直す必要があります。

Routing

Routingとは

Routing(ルーティング)は、HTTPリクエストなどのURLから目的にあわせたプログラムを実行する役割を担います。

URLを分解して処理

URLを「 / 」で分解し、ControllerとActionを判別してサーバープログラムを実行させます。WebシステムにおいてのURLは、何か動作するときに意味を持つ重要な要素です。

MVCのフロー

MVC アーキテクチャーで設計した場合、システムの流れは以下の図のようになります。

例1

以下のURLは、「example.com」以降の文字列を「item」「edit」「1」に分解して意味を持たせています。

http://example.com/item/edit/1
  • ID = 1 の商品を編集する

Controller + Action + ID

よって、システム的には「Controller」「Action」「ID」に分類できます。

http://example.com/Controller/Action/ID

カテゴリーにわける

管理者カテゴリー

次のURLは、管理者「admin」カテゴリーにわけることで、管理者専用の機能となります。

http://example.com/admin/item/edit/1
  • 管理者が ID = 1 の商品を編集する

ユーザカテゴリー

次のURLは、ユーザ「user」カテゴリーにわけることで、ユーザ専用の機能となります。

http://example.com/user/item/edit/1
  • ユーザが ID = 1 の商品を編集する

MVCプログラム

Routingとプログラムファイル

つぎのURLを元に、Routingとプログラムファイルについて考えます。

http://example.com/item/edit/1

Routingとプログラム

役割 URLパス 種別 プログラム
商品の操作 item Controller ItemController
編集 edit Action edit() メソッド
商品ID 1 ID id = 1

MVCとの関係

つぎにMVCでの役割を考えます。

  • ItemControllerクラスを特定
  • ItemControllerの edit() メソッドを実行
  • 「id = 1」の商品データを取得
  • Viewで商品データをHTML表示

MVCプログラム例

これをMVCでプログラムすると以下のようになります。URL に意味を持たせることで、プログラムがルール化して開発することができます。

// (1) ItemController クラスを特定(Controller)
class ItemController {
    //(2) edit() メソッドを実行(Action)
    public function edit(Request $request) {
        //(3) id  から商品取得(Model)
        $item = Item::find($request->id);

        //(4) テンプレートエンジンで View のHTMLレンダリング処理(View)
        return view('item.edit', $item);
    }
}

命名規則

命名規則の重要性

MVCに限らずファイル名、メソッド名、DB、モデルなど命名規則がとても重要です。現実世界で起きていることを英単語や文章で説明できるようにプログラミングするよう心がけるとよいでしょう。

  • 商品モデル:Item(クラスファイルは先頭大文字)
  • 編集する:edit() (Actionはクラスメソッド)
  • 商品名:item.name、item->name、item['name'] など商品の名前という意味

静的HTMLでアウトプット

ファイル名やフォルダ名

プログラムは動的ファイルですが、設計やプロトタイプレベルでは静的HTMLなどを作成するのも良いでしょう。ファイル名やフォルダ名を決めるのは重要な作業です。

HTMLファイル構成の例

商品を編集するプログラム「ItemController->edit()」を想定する場合、「item」フォルダに「edit.html」を作成します。

商品の編集

ItemController->edit()
./item/edit.html

商品の作成

商品の新規追加であれば、「item」フォルダに「create.html」を作成します。

ItemController->create()
./item/create.html

管理者の商品一覧

管理者機能の商品一覧であれば、「admin」フォルダに「 item/index.html」を作成します。

Admin/ItemController->index()
./admin/item/index.html

このように URL から、ファイルやフォルダ名を意識することで、第三者から見てもわかりやすい開発ができます。