0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

現場で実践!MVCモデルの本当の使い方

Posted at

はじめに

「MVCって言葉は知ってるけど、実際どう使うの?」
「Model、View、Controller、それぞれの責任って何?」

私も最初はこんな疑問を持っていました。今回は現場での経験を交えながら、MVCモデルの実践的な使い方を解説していきます。

MVCの本質

MVCは「料理店」のような仕組みで動いています:

Model(料理人) :食材を料理する
View(給仕) :お客様に料理を提供する
Controller(店長) :注文を受け、料理人と給仕の仲介をする

この3つの役割がうまく連携することで、お客様(ユーザー)に最高のサービスを提供できます。

なぜ役割分担が必要なのか

料理店の例で考えてみましょう:

  1. 専門性の確保
    → 料理人は調理に専念できる
    → 給仕はサービスに集中できる
    → 店長は全体の調整に注力できる

  2. 効率性の向上
    → それぞれが得意分野に集中
    → 並行して作業ができる
    → トラブル時の対応が明確

  3. 品質の保証
    → 各工程でのチェックが可能
    → 問題があればすぐに特定できる
    → 改善点が見つけやすい

MVCの具体的な役割

1. Model(料理人)の仕事

# ユーザー情報を管理するモデル
class User < ApplicationRecord
  validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }
  
  def full_name
    "#{first_name} #{last_name}"
  end
  
  def premium_user?
    subscription_status == 'premium' && !subscription_expired?
  end
end

料理人の仕事は:
→ 材料(データ)の管理
→ 調理(ビジネスロジック)の実行
→ 品質(バリデーション)のチェック

2. View(給仕)の仕事

<!-- ユーザープロファイル画面 -->
<div class="user-profile">
  <h1><%= @user.full_name %></h1>
  
  <% if @user.premium_user? %>
    <span class="premium-badge">プレミアム会員</span>
  <% end %>
  
  <div class="user-stats">
    <p>登録日:<%= @user.created_at.strftime('%Y年%m月%d日') %></p>
  </div>
</div>

給仕の仕事は:
→ 料理(データ)の見栄えの良い提供
→ お客様(ユーザー)への適切な対応
→ 快適な体験の提供

3. Controller(店長)の仕事

class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
    @recent_activities = @user.activities.recent
    
    respond_to do |format|
      format.html
      format.json { render json: @user }
    end
  end
  
  def update
    @user = User.find(params[:id])
    if @user.update(user_params)
      redirect_to @user, notice: 'プロフィールを更新しました'
    else
      render :edit
    end
  end
end

店長の仕事は:
→ 注文(リクエスト)の受付
→ 料理人への指示出し
→ 給仕への配膳指示

現場での課題と対策

1. Fat Controller(店長が忙しすぎる)

❌ 悪い例:

def create_order
  # 店長が全部やろうとする
  @order = Order.new(order_params)
  @order.calculate_total
  @order.apply_discount
  @order.check_inventory
  @order.process_payment
  @order.send_confirmation
  # ...
end

⭕️ 良い例:

def create_order
  # 店長は指示を出すだけ
  @order = OrderService.new(order_params).create
  
  if @order.persisted?
    redirect_to @order, notice: '注文が完了しました'
  else
    render :new
  end
end

2. Fat Model(料理人が多すぎる仕事を抱える)

❌ 悪い例:

class Order < ApplicationRecord
  # 料理人が全ての料理を一人で作ろうとする
  def process
    calculate_total
    apply_discount
    check_inventory
    process_payment
    send_confirmation
    # ...
  end
end

⭕️ 良い例:

# 料理を専門のシェフに分担する
class Order < ApplicationRecord
  def process
    OrderCalculator.new(self).calculate
    PaymentProcessor.new(self).process
    NotificationService.new(self).send_confirmation
  end
end

3. Fat View(給仕が余計な仕事をする)

❌ 悪い例:

<div class="order-summary">
  <% total = 0 %>
  <% @items.each do |item| %>
    <% price = item.price * (1 - discount_rate) %>
    <% total += price %>
    <!-- 給仕が計算までしている -->
  <% end %>
  <p>合計: <%= total %></p>
</div>

⭕️ 良い例:

<div class="order-summary">
  <% @order.items.each do |item| %>
    <%= render 'item', item: item %>
  <% end %>
  <p>合計: <%= @order.calculated_total %></p>
</div>

実務での選択基準

MVCを厳格に守るべき場合

→ 大規模なチーム開発
→ 長期的なメンテナンスが必要
→ 機能の追加・変更が頻繁
→ テストの書きやすさが重要

柔軟に運用して良い場合

→ 小規模な開発
→ プロトタイプの作成
→ 短期的なプロジェクト
→ 一人での開発

まとめ

MVCは料理店のように:
→ Model(料理人):データとロジックを扱う
→ View(給仕):ユーザーとの接点を担当
→ Controller(店長):全体の流れを管理

実践のポイント:
→ 役割分担を明確に
→ 責任範囲を守る
→ 必要に応じて柔軟に対応

結局のところ:
→ MVCは「理想的な組織体制」の一つ
→ プロジェクトの規模や要件に応じて適切に運用
→ 完璧を求めすぎないことも重要

現場での経験を積みながら、プロジェクトに合った最適なMVCの形を見つけていくことが大切です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?