
MVP(Model–View–Presenter)は、MVCを発展させたパターンです。
MVCの「Controller」を改良して、UIロジックをテストしやすく・再利用しやすくするのが特徴です。
特にGUI(Webフォーム、スマホアプリ)でよく使われる構造なんです。
基本構造
View(画面)
UI描画・イベント通知
↓
Presenter(司令塔)
ViewとModelを仲介
↓
Model(データ)
ビジネスロジック・状態管理
各役割の説明
Model(モデル)
データやビジネスロジック。
データ更新時には通知を出さない(Observerを持たないことが多い)。
View(ビュー)
UIの表示専用。
自身ではロジックを持たず、操作イベントをPresenterに委ねる。
Presenter(プレゼンター)
ViewとModelの仲介役。
Modelの結果を受け取ってViewを更新。
Viewとはインターフェイスを介して通信する。
サンプルコード
<div id="app">
<h1 id="count">0</h1>
<button id="increment">+</button>
<button id="decrement">−</button>
</div>
<script>
// Model(データ)
class CounterModel {
constructor() {
this.value = 0;
}
increment() { this.value++; }
decrement() { this.value--; }
getValue() { return this.value; }
}
// View(UI)
class CounterView {
constructor() {
this.countEl = document.getElementById("count");
this.incBtn = document.getElementById("increment");
this.decBtn = document.getElementById("decrement");
}
bindIncrement(handler) {
this.incBtn.addEventListener("click", handler);
}
bindDecrement(handler) {
this.decBtn.addEventListener("click", handler);
}
render(value) {
this.countEl.textContent = value;
}
}
// Presenter(司令塔)
class CounterPresenter {
constructor(view, model) {
this.view = view;
this.model = model;
this.view.bindIncrement(() => this.handleIncrement());
this.view.bindDecrement(() => this.handleDecrement());
this.updateView();
}
handleIncrement() {
this.model.increment();
this.updateView();
}
handleDecrement() {
this.model.decrement();
this.updateView();
}
updateView() {
this.view.render(this.model.getValue());
}
}
// 起動
new CounterPresenter(new CounterView(), new CounterModel());
</script>
特徴まとめ
| 要素 |
役割 |
主なポイント |
| Model |
データ・ビジネスロジック |
プレゼンターからのみ呼ばれる |
| View |
画面表示・イベント通知 |
プレゼンター経由で更新される |
| Presenter |
ロジック制御・仲介役 |
Viewとはインターフェース越しに通信 |
メリット
・Viewをモック化してテスト可能(UIを触らずロジック検証)。
・ビューとロジックが完全に分離されている。
・Presenterの再利用性が高い。
デメリット
・小規模アプリではクラス構成が冗長。
・Presenterが肥大化しやすい(God Presenter化)。
・双方向データバインディングがないため、手動更新が必要。
MVPを使っている代表的な技術
| 技術 |
MVCスタイルの採用例 |
| Android開発 |
Google公式アーキテクチャ(古典型) |
| Webフロント |
Vanilla JSやjQuery時代の構造 |
| デスクトップ |
WinForms / WPF初期の設計 |
| PHP |
CodeIgniter(MVCとMVPの中間構造) |
MVCとの違い
| 比較項目 |
MVC |
MVP |
| 仲介役 |
Controller |
Presenter |
| Viewからの更 |
Model監視(Observer) |
Presenterが直接制御 |
| 双方向通信 |
Model↔View(あり) |
View→Presenter→Model(片方向) |
| テストのしやすさ |
中程度 |
高い |
| 主な用途 |
Webサーバー・GUI |
GUI・SPA・ネイティブアプリ |
あとがき
MVPはMVCは、置き換えられているControllerに比べて、Presenterが構造化されている違いがわかります。
HTMLのDOM構造を操作するWebシステムの場合は、こちらのほうが、設計・管理しやすくなることが分かりますね。
この2つはさほど大きく違うわけではないのですが、設計する上で重要なのが、フォルダ構成です。
主要なフレームワークでは、Model,View,Presenter(Controller)をそれぞれ同列階層のフォルダでその中にクラスに適応したファイル名で配置するパターンが多いようです。
ちなみに、この時のクラスファイルは、1ファイル1クラスが鉄則のようですね。
このパターンを理解して、いろいろなフレームワークの構造や、その内部コードを見てみると、設計ルールを作る参考になるかもですね。
0 件のコメント:
コメントを投稿