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

多層アーキテクチャ MVC・MVVM・DDD

概要

  • 日程: Day 3 / セッション 3
  • 時間: [10:30-11:00]
  • 形式: 座学
  • ゴール: 3層アーキテクチャの各層の役割を、家計簿システム等の具体例を挙げて(条件)説明できる。MVCとMVVMの違い、DDDの主要概念(ドメイン、ドメイン層、ユビキタス言語、ドメインモデル)をそれぞれ一言ずつ言える(行動・基準)
  • 学習形式: 対話型解説

導入(5分)

Day 2 で皆さんは、情報モデルの状態遷移から「機能」と「プレゼンテーション」を分離して抽出しました。
ここで少し考えてみてください。あの「分離」、世界中のエンジニアはどう呼んでいるでしょうか?

答えは「多層アーキテクチャ」です。皆さんがDay 2 でやったことは、業界標準の設計そのものでした。今日はその標準に正式な名前をつけ、語彙を業界共通のものにアップグレードします。

前のセッションで皆さんは設計アプローチを選び、根拠を言葉にしました。このセッションで学ぶ多層アーキテクチャは、選んだアプローチを実装の構造に落とすときの定番の型です。3層アーキテクチャ → MVC → MVVM → DDD の順に、粗い分離から洗練された分離へと進みます。

本編(20分)

1. 3層アーキテクチャ 分離の業界標準

3層アーキテクチャは、システムを役割の違う3つの層に分ける定番の型です。
これはレストランのようなものです。客席(見せる場所)・厨房(調理する場所)・食材庫(保存する場所)が分かれているから、メニュー改定でも厨房ごと作り直す必要がありません。

役割 レストランなら 家計簿システムなら
プレゼンテーション層 見せる・入力を受ける 客席・メニュー 支出一覧画面、入力フォーム
ロジック層 業務のルール・計算 厨房 月次集計、予算超過の判定
データ層 保存する・取り出す 食材庫 支出テーブルへの読み書き
flowchart TB P["プレゼンテーション層
(画面・入力)"] -->|操作・入力| L["ロジック層
(業務ルール・計算)"] L -->|結果| P L -->|保存・取得の依頼| D["データ層
(DB読み書き)"] D -->|データ| L

大事なルールは「層をまたぐ会話は隣同士だけ」です。画面がDBに直接SQLを投げる構成は3層アーキテクチャに該当しません。一方、画面がロジック層に「今月の合計をください」と頼み、ロジック層がデータ層に取得を依頼する構成は該当します。なぜなら、前者は画面とDBが密結合になり、DBの変更が全画面に波及してしまうからです。

Day 2 の成果物と対応づけると、こうなります。

  • プレゼンテーション一覧・ワイヤーフレーム → プレゼンテーション層
  • 機能一覧(CRUD由来の機能) → ロジック層
  • 情報モデル → データ層(明日、テーブル設計に変換します)

コード例・実例

「今月の食費合計を表示する」を、層の分離なし/ありで比べます。

// 分離なし: 画面のボタン処理にSQLも計算も混在(アンチパターン)
button.onclick = async () => {
  const rows = await db.query("SELECT * FROM expenses"); // 画面がDB直叩き
  let sum = 0;
  for (const r of rows) if (r.category === "食費") sum += r.amount;
  label.textContent = sum + "円";
};

// 分離あり: 画面はロジック層に頼むだけ
button.onclick = async () => {
  const sum = await expenseService.monthlyTotal("食費"); // ロジック層
  label.textContent = sum + "円";
};

分離ありの形なら、DBをファイル保存に替えても、画面のコードは1行も変わりません。

ここがポイント

  • 3層の本質は「変更の影響範囲を層の中に閉じ込める」こと
  • Day 2 の「機能とプレゼンテーションの分離」=プレゼンテーション層とロジック層の分離。皆さんはすでに実践者
  • 明日のDay 4 実装は「プレゼンテーション層(UI)+ロジック/データ層(モックAPI)」という3層構成そのもの

コラム

3層アーキテクチャが広まった1990年代、その前の主流は「クライアント/サーバ2層」でした。画面アプリがDBに直接つなぐ構成です。業務ルールを変えるたびに、全社員のPCのアプリを入れ替えて回る必要があり、情報システム部門はフロッピーディスクを抱えて社内を行脚したそうです。「ロジックを真ん中の層に集めれば配り直さなくて済む」——3層アーキテクチャの普及の裏には、この行脚からの解放という切実な事情がありました。

2. MVCとMVVM プレゼンテーション層の中の分離

3層のうちプレゼンテーション層は、さらに内部を分けるのが定番です。その代表が MVC です。

  • Model: 扱う情報とルール(例: 支出レコード、金額は0以上)
  • View: 見せる部分(例: 支出一覧画面)
  • Controller: 入力を受けてModelとViewを仲介(例: 「登録」ボタン→Modelの更新を指示)
flowchart LR U["利用者"] -->|操作(登録ボタン)| C["Controller
(登録処理の仲介)"] C -->|更新指示| M["Model
(支出レコード)"] M -->|変更の通知| V["View
(支出一覧画面)"] V -->|表示| U

家計簿でいえば、Model=支出レコード、View=支出一覧画面、Controller=登録処理の仲介、という対応です。

MVVM はMVCの発展形で、Controllerの代わりに ViewModel を置きます。最大の特徴はデータバインディングです。これは、ViewとViewModelを自動同期の紐で結ぶ仕組みです。ViewModelの値が変わればViewが勝手に更新され、Viewの入力は勝手にViewModelへ反映されます。

MVCとMVVMの違いを一言でいうと、こうなります。

  • MVC: Controllerが「Modelを更新しろ」「Viewを描け」と手続きで仲介する
  • MVVM: ViewとViewModelがバインディングで自動同期され、仲介コードが激減する

「ボタンを押したらJSで label.textContent を書き換える」コードはMVVMのバインディングには該当しません。一方、Vue.jsの {{ total }} のようにデータを宣言的に結びつけて自動更新されるものは該当します。なぜなら、バインディングとは「同期処理を自分で書かないこと」だからです。

コード例・実例

同じ「合計金額の表示更新」をMVC風とMVVM風(Vue.js)で比べます。

// MVC風: Controllerが手続きで同期させる
class ExpenseController {
  addExpense(amount) {
    this.model.add(amount);                        // Modelを更新し、
    this.view.renderTotal(this.model.total());     // Viewの描画を指示する
  }
}
<!-- MVVM風 (Vue.js): バインディングが自動で同期する -->
<p>合計: {{ total }} 円</p>
<button @click="expenses.push({ amount: 500 })">追加</button>
<!-- total は expenses から自動計算され、画面も自動更新される -->

MVVM側には「Viewを更新せよ」というコードがどこにもない点に注目してください。

ここがポイント

  • MVCもMVVMも「3層と対立する概念」ではなく、プレゼンテーション層の内部整理の型
  • MVVMのデータバインディングは、React/Vue等の現代フレームワークの基盤概念。明日UIを作るときに再会する
  • どちらが優れているかではなく、フレームワークがどちらの型を前提にしているかで決まることが多い

分からなくなったらAIに「MVCの登場人物を家計簿システムの登場人物に置き換えて」と質問してみましょう。自分のテーマに置き換えるのが最短の理解ルートです。

コラム

MVCの生みの親はノルウェーのトリグヴェ・リーンスカウグ。1979年、客員研究者として滞在したXerox PARC(マウスもGUIもここ生まれという伝説の研究所)で、Smalltalkのために考案しました。原型の名前は「Model-View-Controller-Editor」で、最初は「Thing-Model-View-Editor」というさらに素朴な名前だったそうです。「Thing(モノ)」が最終的に「Model」になったわけで、命名に苦労する姿は40年前の天才も同じだったようです。

3. DDD ドメインを中心に据える

最後は DDD(ドメイン駆動設計) です。主要概念は4つ。それぞれ一言で言えるようにしましょう。

  • ドメイン: ソフトウェアが対象とする問題領域(例: 「家計の管理」という業務そのもの)
  • ドメイン層: 業務ルールを集める層。3層のロジック層のうち「業務の本質」部分を独立させたもの
  • ユビキタス言語: 開発者と業務側が同じ用語を使う共通言語(例: 「費目」と呼ぶと決めたら、会話でもコードでも「費目(category)」で統一)
  • ドメインモデル: ドメインの概念と関係をモデル化したもの(例: 「支出は1つの費目に属する」を表現したモデル)

ここで気づいてほしいことがあります。ユビキタス言語、どこかで見覚えがありませんか?

そう、Day 1 で作った情報定義書です。「この情報を何と呼び、どういう意味か」をチーム(皆さんの場合は自分とAI)で統一する——情報定義書はユビキタス言語の辞書そのものです。そしてドメインモデルは、Day 2 の情報モデルとほぼ同じ役割です。皆さんはDDDの中心概念を、名前を知らないまま実践してきたことになります。

「DBのテーブル名はexpense、画面では『お小遣い帳の記録』、会話では『レシート』と呼ぶ」状態はユビキタス言語に該当しません。一方、「情報定義書で『支出』と定め、コードもAPIも会話も『支出(expense)』で通す」状態は該当します。なぜなら、ユビキタス言語の目的は「翻訳による誤解をなくすこと」だからです。

コード例・実例

ドメイン層のイメージです。業務ルール「予算超過の判定」がドメイン層に集まっています。

// ドメイン層: 「家計の管理」の業務ルールだけを持つ
class MonthlyBudget {
  constructor(limit) { this.limit = limit; this.expenses = []; }
  addExpense(expense) { this.expenses.push(expense); }
  total() { return this.expenses.reduce((s, e) => s + e.amount, 0); }
  isOverBudget() { return this.total() > this.limit; }  // 業務ルール
}
// 画面もDBも登場しない。「家計の言葉」だけで書かれている点がドメイン層らしさ

このクラスには画面(View)もSQL(データ層)も出てきません。ユビキタス言語(予算・支出・超過)だけで書かれています。

ここがポイント

  • DDDは「技術ではなくドメイン(業務)を設計の中心に据える」思想。前セッションの軸でいえば「ドメイン中心アプローチ」
  • ユビキタス言語 ≒ 情報定義書、ドメインモデル ≒ 情報モデル。IAとDDDは「情報(業務の言葉)から始める」仲間
  • DDDの全体は分厚い。今日は4概念を一言ずつ言えれば合格。深入りはAIと少しずつ

コラム

DDDを提唱したエリック・エヴァンスの著書(2003年)は、通称「エヴァンス本」。約560ページの大著で、「買ったが最後まで読めない技術書」の常連としても有名です。あまりに挫折者が多いため、世界中で入門書・要約本(『DDD Quickly』等)が出版されるという珍しい現象が起きました。それでも中心の主張はシンプルで、「ソフトウェアの複雑さと戦う武器は、業務を語る言葉そのものだ」ということ。皆さんが情報定義書で体験したことです。

💬 AIに聞いてみよう

  • 「私の開発テーマ◯◯を3層アーキテクチャに分けると、各層には何が入りますか?機能一覧を貼るので割り当ててください」
  • 「MVCとMVVMの違いを、データバインディングの有無に注目して、コード例つきで説明してください」
  • 「私のDay1の情報定義書はDDDのユビキタス言語としてどこまで使えますか?足りない観点を指摘してください」

まとめ(5分)

今回学んだことを一言でまとめると「Day 2 でやった機能とプレゼンテーションの分離は、多層アーキテクチャという業界標準そのものであり、MVC/MVVM/DDDはその分離を洗練させた型である」です。

  • 3層アーキテクチャ: プレゼンテーション・ロジック・データの分離。変更を層に閉じ込める
  • MVC/MVVM: プレゼンテーション層の内部整理。MVVMはバインディングで自動同期
  • DDD: ドメインを中心に据える思想。ユビキタス言語は情報定義書の親戚

次のセッションは演習です。「アーキテクチャ」「設計」「駆動」「アプローチ」「パターン」——今日大量に出てきたこれらの用語そのものを、Day 1 で学んだIAの手法(カードソーティング)で整理・分類します。IAが「設計知識」という情報にも効くことを確かめましょう。

🔄 振り返りチェック

  • 3層アーキテクチャの各層の役割を、家計簿システムを例に言えますか?
  • MVCとMVVMの違いを「データバインディング」という言葉を使って一言で言えますか?
  • ユビキタス言語とは何か、自分のDay 1 の成果物と関連づけて説明できますか?

補足資料

  • 参考リンク:
    • 『エリック・エヴァンスのドメイン駆動設計』: DDDの原典(通称エヴァンス本)
    • Martin Fowler「GUI Architectures」: MVC等のGUIパターンの歴史的整理
    • 『Clean Architecture』(Robert C. Martin): 層の依存方向を突き詰めた発展形
  • 発展課題:
    • 使ったことのあるWebフレームワーク(Express、Ruby on Rails、Vue.js等)が、MVC/MVVMのどの型に近いかAIと調べてみましょう
    • 自分の情報モデルの1つを「ドメイン層のクラス」としてJavaScriptで書き、業務ルールを1つメソッドにしてみましょう

学習ガイド

想定される質問と回答例

質問 ヒント
3層アーキテクチャとMVCは何が違うのですか? 粒度が違う。3層はシステム全体の分離、MVCはそのうちプレゼンテーション層の内部の分離。対立ではなく入れ子の関係
ModelとViewModelとドメインモデルは同じもの? 全部別物なので注意。MVCのModelは「画面が扱う情報とルール」、ViewModelは「View専用に整形した状態」、ドメインモデルは「業務概念のモデル」。名前が似ているのは歴史の事故
DDDは小さな個人開発でも使うべきですか? フル装備は過剰なことが多い。ただしユビキタス言語(用語統一)とドメインモデルの意識だけは小規模でも効く。情報定義書を作った皆さんはすでに実践している
MVVMのデータバインディングは魔法に見えます。仕組みは? フレームワークがデータの変更を検知(プロキシや監視)して再描画する。Day4でVue/React等に触れると具体像がつかめる。AIに「Vueのリアクティビティの仕組みを初心者向けに」と聞いてみよう

つまずきやすいポイント

つまずきポイント ヒント
「層」と「MVC」の関係が混ざる 入れ子で覚える。システム全体=3層、そのプレゼンテーション層の中身=MVC/MVVM。地図の縮尺が違うだけ
MVCの矢印(誰が誰を呼ぶか)を暗記しようとして混乱する 流派により矢印は微妙に違うので暗記は不毛。「入力はControllerへ、表示はViewが、情報とルールはModelが」という役割分担だけ押さえる
DDDの用語(ドメイン/ドメイン層/ドメインモデル)が区別できない 「ドメイン=問題領域そのもの、ドメイン層=それをコードで置く場所、ドメインモデル=その表現物」。家計簿なら「家計管理/MonthlyBudgetクラスを置く層/支出と費目の関係図」
ユビキタス言語を新しい特別な技術だと思ってしまう 技術ではなく「用語統一の約束」。Day1の情報定義書がほぼそれ。自分の成果物と結びつければ一気に身近になる
読み上げを開始します...

AIに質問する