📖 テーマ設定
🔊 音声設定
1.2
1.0
1.0
▶️ 再生コントロール
🎵 BGM設定
0.3
🔔 効果音設定
0.3

(演習)開発テーマをMVCで分解してみる

概要

  • 日程: Day 3 / セッション6
  • 時間: [13:00-13:30]
  • 形式: 演習
  • ゴール: 開発テーマの機能を1つ選び、Model・View・Controllerに分解できる
  • 学習形式: AIペアプログラミング

導入(5分)

🗣️ 要約

  • MVCの3文字はModel・View・Controllerで、3層アーキテクチャのデータ層・ロジック層・プレゼンテーション層に対応する
  • 開発テーマの機能を1つ選び、実際にMVCへ分解する演習を行う

午前中に、3層アーキテクチャとMVC、MVVMの対応関係を学びました。「データ層」「ロジック層」「プレゼンテーション層」という3つの層が、MVCでは「Model」「Controller」「View」という3つの役割に対応していましたね。

ここで少し思い出してみてください。MVCの3文字、それぞれ何を指していたか、パッと言えるでしょうか?

言えなくても大丈夫です。このセッションでは、実際に自分たちの開発テーマの機能を1つ選び、MVCに分解する作業を通して体に染み込ませます。読んで理解するより、手を動かして分解したほうが記憶に残ります。

このセッションが終わる頃には、自分たちのシステムの「どの部分がModelで、どの部分がViewで、どの部分がControllerか」を指差しで説明できるようになっています。

本編(20-40分)

🗣️ 要約

  • MVCは「厨房(Model)」「配膳係(View)」「注文票(Controller)」の関係にたとえられる
  • Viewに業務ロジックを書いてしまうのがMVCで最もよくあるつまずき
  • DDDのドメインモデルは、Modelの中でも業務ロジックそのものを指す

1. MVCの3つの役割をもう一度、具体例で

🗣️ 要約

  • Model=厨房(データ管理・計算処理)、View=盛り付け(表示)、Controller=注文票係(利用者操作の仲介)
  • 家計簿システムの「今月の支出合計を見る」例では、操作はView、集計依頼はController、計算はModel、結果表示はView
  • 計算ロジック(Model)と表示上の工夫(View)を混同してしまうのがよくあるつまずき

MVCは、いわば「厨房」「配膳係」「注文票」の関係のようなものです。

  • Model(モデル)は「厨房」です。材料(データ)を管理し、実際に調理(ロジック処理)をする場所です
  • View(ビュー)は「お客様に出てくる皿の盛り付け」です。見た目・表示のことだけを担当します
  • Controller(コントローラ)は「注文票を受け取り、厨房に伝え、できた料理を配膳係に渡す係」です

たとえば「家計簿システム」で、利用者が「今月の支出合計を見る」というシーンを考えてみましょう。

  • 利用者が「今月の支出合計を見せて」とボタンを押す → これはViewへの操作です
  • ボタンが押されたことを受け取り、「集計処理をしてほしい」とModelに伝えるのがControllerです
  • 支出データを合計する計算処理をするのがModelです
  • 計算結果を画面に表示する担当がViewです

一方で、「今月の支出合計はいくらか」という計算ロジック自体はModelに属しますが、「合計金額を赤字で強調して見せる」という表示上の工夫はViewに属します。ここを混同して、Viewの中に集計ロジックを書いてしまうのが、MVCで最もよくあるつまずきです。

ここまでで、Model・View・Controllerの役割のイメージはできたでしょうか。次は、自分たちの開発テーマで実際に分解してみましょう。

コード例・実例

厳密なコードではなく、役割分担の疑似コードで示すとこうなります。

// Controller(注文票係)
function onShowMonthlyTotalClicked() {
  const total = Model.calculateMonthlyTotal();  // Modelに計算を依頼
  View.renderTotal(total);                      // Viewに表示を依頼
}

// Model(厨房)
function calculateMonthlyTotal() {
  return expenses.reduce((sum, e) => sum + e.amount, 0);
}

// View(配膳係)
function renderTotal(total) {
  document.querySelector("#total").textContent = `${total}円`;
}

Controllerは「誰に何をお願いするか」を仲介するだけで、自分では計算も表示もしていない点に注目してください。

ここがポイント

特に注意してほしいのは、ControllerにModelの計算ロジックを書いてしまう間違いです。「ボタンを押したらその場で合計を計算して表示する」という1つの関数にまとめてしまうと、後で「表示だけスマホアプリに変えたい」となったときに、計算ロジックごと書き直すことになります。ModelとViewを分けておけば、Viewだけ差し替えられます。これが「プレゼンテーションと機能を分離する」(到達目標No.5)の具体的な意味です。

コラム

MVCという考え方は、実は1970年代の終わり、Xerox社の研究所でSmalltalkというプログラミング言語のために生まれました。考案者のトリグヴェ・リーンスカウグは、最初「Thing-Model-View-Editor」という名前を考えていたそうです。「Thing(モノ)」も入っていたわけです。もし当時のまま名付けられていたら、私たちは今日「TMVEで分解してみよう」と言っていたかもしれません。ちなみに、現在世の中にある「MVCフレームワーク」を名乗るツールは、実はそれぞれ微妙に解釈が違います。「これのどこがMVCなんだ」と開発者同士で議論になることも多く、MVCは50年近く経った今でも現役の論争の種なのです。

2. DDDのドメインモデルとMVCのModelの関係

🗣️ 要約

  • ドメインモデルは、Modelの中でも「業務ロジックそのもの」を指す
  • DDDは業務ルールをドメインモデルとして切り出し、ユビキタス言語で会話できるようにする考え方
  • 業務ルールをViewに書いてしまうと、Web版とスマホ版でルールがズレる事故につながる

午前中に触れたドメイン駆動設計(DDD)を思い出してください。DDDでは「ドメインモデル」という言葉が出てきました。

ドメインモデルは、MVCのModelの中でも特に「業務ロジックそのもの」を指す、と考えるとイメージしやすくなります。Modelという箱の中に、単純なデータ(家計簿の1件の支出データ)と、業務ルール(「支出が予算を超えたら警告する」といったロジック)が両方入っているとします。DDDは、この業務ルールの部分を「ドメインモデル」として明確に切り出し、専門用語(ユビキタス言語)を使ってチーム全員が同じ言葉で会話できるようにする考え方です。

なぜこの区別が大事なのでしょうか。少し考えてみてください。もしチームの誰かが「予算超過の警告ロジック」を「単なる表示の一部」だと思い込んでViewに書いてしまったら、何が起きるでしょうか。おそらく、Web版とスマホ版で警告のルールが微妙にズレてしまう、という事故につながります。

💬 AIに聞いてみよう

🗣️ 要約

  • 自分たちの機能がMVCのどれに当たるか、ドメインモデルとMVCのModelの関係、Controllerが肥大化しない工夫などをAIに質問できる

ここまでの内容で疑問があれば、AIに質問してみましょう。たとえば:

  • 「自分たちの開発テーマの◯◯という機能は、Model・View・Controllerのどれに当たる?」
  • 「ドメインモデルとMVCのModelは、結局同じもの?違うもの?」
  • 「Controllerが太りすぎて何でも屋になってしまうのを防ぐには?」

実習・演習(該当する場合)

🗣️ 要約

  • 開発テーマの機能を1つ選び、Model・View・Controllerに分解する演習

課題

🗣️ 要約

  • 機能を1つ選び、Model・View・Controllerの役割を1〜2文で書き出し、業務ルールがあればドメインモデルに当たることを確認し、チームで発表してViewに書いてしまいそうなロジックがないか相互チェックする
  1. 開発テーマの機能の中から1つを選ぶ(例:「支出を登録する」「検索結果を表示する」など)
  2. その機能を、Model・View・Controllerの3つに分解し、それぞれが「何をする係か」を1〜2文で書き出す
  3. その機能の中に「業務ルール」と呼べる部分があれば、それがドメインモデル(Modelの中核)に当たることを確認する
  4. チームで発表し、「View に書いてしまいそうになったロジック」がなかったか、お互いにチェックする

成果物

🗣️ 要約

  • MVC分解メモ(機能名・Model担当・View担当・Controller担当を1枚にまとめたもの)
  • MVC分解メモ(機能名・Model担当・View担当・Controller担当を1枚にまとめたもの)

ヒント

🗣️ 要約

  • 「見た目の話か、計算・判断の話か」で切り分けると分類しやすい
  • うまく3つに分けられない場合は機能が大きすぎる可能性があり、より小さい単位に絞るとよい
  • AIに「この機能をMVCで分解して」と伝えて自分たちの分解結果と見比べるのも有効
  • 迷ったら「これは見た目の話か、それとも計算・判断の話か」で切り分けてみましょう
  • うまく3つに分けられない場合は、機能が大きすぎる可能性があります。もっと小さい単位(ボタン1つ分の操作)に絞ってみてください
  • AIに「この機能をMVCで分解して」と伝え、自分たちの分解結果と見比べてみるのも有効です

まとめ(5分)

🗣️ 要約

  • 見た目(View)・制御(Controller)・業務ロジック・データ(Model)を混ぜずに分けることが、変更に強いシステムを作る
  • 次回は「永続化」を学び、Model内の業務データがデータベースやファイルに保存される仕組みを見る

今回学んだことを一言でまとめると、「見た目(View)」「制御(Controller)」「業務ロジック・データ(Model)」を混ぜずに分けることが、変更に強いシステムを作るということです。

次回は「永続化」を学びます。今日Modelの中に置いた業務データが、実際にどうやってデータベースやファイルに保存されるのかを見ていきます。今日の「Model」のイメージが土台になるので、しっかり復習しておきましょう。

🔄 振り返りチェック

🗣️ 要約

  • Model・View・Controllerそれぞれの役割を自分の言葉で説明できるか
  • 業務ロジックをViewに書いてしまうとどんな問題が起きるか説明できるか

以下の問いに答えられるか確認してみましょう:

  • Model・View・Controller、それぞれの役割を自分の言葉で説明できますか?
  • 「業務ロジックをViewに書いてしまう」とどんな問題が起きるか説明できますか?

答えに自信がない場合は、該当部分を読み返すか、AIに質問してみてください。

補足資料

🗣️ 要約

  • 参考リンクは特になく、使用するフレームワークの公式ドキュメントのMVC説明ページが参考になる
  • 発展課題は、性質の異なる別の機能(一覧表示と新規登録など)をもう1つ選んでMVCで分解すること
  • 参考リンク: なし(社内資料としては、各自のチームで使用するフレームワーク公式ドキュメントのMVCに関する説明ページを参照するとよい)
  • 発展課題: 自分たちが選んだ開発テーマの機能をもう1つ選び、同様にMVCで分解してみる。特に「一覧表示」と「新規登録」のように性質の異なる機能を選ぶと、ControllerとModelの役割の違いがより明確になる

学習ガイド

🗣️ 要約

  • 受講者からよく出る質問への回答例と、つまずきやすいポイントへの対処法をまとめている

このセクションは、受講者が理解を深めることをサポートする参考情報です。

想定される質問と回答例

🗣️ 要約

  • Viewは「何を表示するか」、Controllerは「操作をどう処理するか」を担う
  • MVVMはViewModelがViewとModelの状態同期を自動化する点でMVCと異なる
  • ドメインモデル(業務ルールの概念モデル)とテーブル設計(永続化の技術的な形)は別物
質問 ヒント
ViewとControllerの境目が分からない 「画面に何を表示するか」を決めるのがView、「利用者の操作をどう処理するか」を仲介するのがControllerと整理する。迷う機能は、まず小さく分割してみると境目が見えやすい
MVVMとMVCは何が違うのか MVVMはViewModelという仲介役がViewとModelの間の状態同期を自動的に行う点が異なる。今回のMVC演習では、まずController自身が仲介する古典的な形で分解の練習をしていることを伝える
ドメインモデルとテーブル設計は同じものか 違う。ドメインモデルは業務ルールを表す概念モデルであり、テーブル設計はそれを永続化するための技術的な形。次回の「永続化」セッションで扱うインピーダンス・ミスマッチの伏線として触れておくとよい

つまずきやすいポイント

🗣️ 要約

  • Controllerに計算ロジックまで書いてしまいやすい
  • 機能が大きすぎて3つに分解しきれないことがある
  • Viewに業務ルール(予算超過の判定など)を書いてしまいやすい
つまずきポイント ヒント
Controllerに計算ロジックまで書いてしまう 「Controllerは仲介役に徹する」というルールを再確認させる。疑似コード例のControllerが1行も計算していない点を見比べさせる
機能が大きすぎて3つに分解しきれない 機能をボタン1つ分の操作単位まで小さくしてから分解し直すよう促す
Viewに業務ルールを書いてしまう(例:予算超過の判定を画面側で行う) 「その判定ロジックを、表示方法をWebからスマホアプリに変えても使い回せるか」を問いかけ、使い回せないならViewに書きすぎているサインだと気づかせる
読み上げを開始します...

AIに質問する