Java好き

カテゴリ: パターン

MVCの本質は「疎結合」にある。

MVCをベースとするとこで、
自然と疎結合なクラスを作成することができる。

元来はsmalltalkにおけるウィンドウプログラム開発の
設計指針として生まれた。

「疎結合」が数多くのメリットを生み出すので、
多くのアプリケーションでMVCがベースとなっている。

MVCの構成

MVCでは、
アプリケーション全体を「モデル」と「ビュー」と「コントローラ」に
分けるようにする。

mvc

それぞれの役割は次のようになる。

役割 概要
ビュー モデルの表示を提供する。通常、ビューは表示に必要な状態とデータをモデルから直接取得する。
コントローラ ユーザ入力を受け取り、それがモデルにとってどのような意味を持つのか解釈する。
モデル すべてのデータ、状態、アプリケーションロジックを提供する。

シナリオ

MVCは次のようなシナリオで動作するように作る。
(順番は図の番号と対応)

  1. ユーザがUIを通してViewに入力する。
  2. ビューに対して何かを実行すると、実行したことをビューがコントローラに通知する。
    (リスナーが反応して、ビューがコントローラの対応するメソッドを呼び出す。)
  3. コントローラがモデルに状態を変更するように依頼する。
  4. コントローラがビューに変更を依頼する場合もある。
  5. モデルの状態が変わった際に、モデルがビューに通知する。
  6. ビューがモデルに状態を要求する。

MVCの本質は「疎結合」にある

MVCの構成とシナリオは上記の通り。
では、なぜこんなに分割したりするのだろうか。

こんなに分割を行っているその理由は
「疎結合」にすることにある。

モジュール間を「疎結合」にすることは、
メンテしやすいプログラムには欠かせない要素である。

ビューに関するコードやビジネスロジックに関するコードが
1カ所に集中していたら、メンテが大変なのは誰にでも想像がつく。

なので、ビューに関するコードとその他を分けることになるが
MVCではさらに「コントローラ」をはさむことで柔軟性を増している。

これによって、
「ビュー」あるいは「モデル」で変更が生じても
「コントローラ」が吸収するかたちとなるので、
「ビュー」と「モデル」の間は単純に分割するより疎結合
となっている。

MVCの「疎結合」がもたらした分業化

「疎結合」化が進んだことにより、
MVCではユニットテストが書きやすくなったり、
プログラムのメンテに関する恩恵が受けられることになる。

ただ、「疎結合」がもたらす効果は
それだけではない。

忘れてはいけないのが「分業化」。

「ビュー」と「モデル」の疎結合になっていくのにともない、
それぞれ並行して作業したり、それぞれを専門に行うようになった。

例えば、「ビュー」で考えるとわかりやすい。
Webなどではビューの部分(html)を
デザイナーに依頼していると思われるサイトはいくつもある。

今や「デザイン」と「ロジック」の分業は常識である。

このことを考えるとそれを後押ししたMVCは、
ソフトウェアパターンとしての恩恵以上に
産業的インパクトも計り知れない存在でもある。

「MVC」と「MVCモデル2」は違う。

「MVC」をWebに対応させた「MVCモデル2」(MVC2)がある。
「MVC」は基本的にウィンドウベースのGUIに対応したものになる。
よってWebではそのまま利用できないので、「MVCモデル2」が登場する。

「MVCモデル2」もWebシステムではほとんどのベースとなっていて、
こちらをMVCと思い込んでいる人も多いが違う。

「モデル2」の構成

MVCとは違い「モデル」から「ビュー」への通知がなくなる。

mvc2

「モデル2」のシナリオ

モデル2は次のようなシナリオで動作するように作る。
(順番は図の番号と対応しています。)

  1. ユーザがブラウザを通してフォームなど入力する。
  2. ユーザが入力したフォームデータなどをHTTPリクエストとして
    ブラウザがコントローラへ送る。
  3. コントローラがモデルに状態を変更するように依頼する。
  4. コントローラが制御をビューに転送する。
  5. ビューがモデルの情報を取得し、
    最新の状態にしたページを生成する。
  6. ページがブラウザに返され、表示される。

「MVC」と「モデル2」の違い

「MVC」との違いは、
「モデル」が「ビュー」に状態が変わったことを通知することが
Webの性質上なくなった点。

サーバー側から「モデル」の状態変更が通知することは
HTTPではできないので、必然的にそうなる。

大したことのない変化に思えるが、
これにともない「MVC」と「モデル」構成の考え方が大きく変わる。

「モデル」が状態が変わったことを通知することができないことは、
毎回最新の状態のモデルを作ることにつながる。

「MVC」では前状態を保持しつつ状態変化に対応させるといった
「モデル」の使い回しがしやすい。

しかし「モデル2」では毎回最新の状態のモデルを作るので
使い切りになる。

この「使い回し」か「使い切り」にするかにより、
モデルを構成する状態やメソッドの設計は大きく影響される。

「使い切り」を前提とすると、
DBから取得した値をどう保持するかに全力を注いで
満足してしまう。

よって「モデル2」では、
DBから取ってきた値を保持するだけのオブジェクトが
必然的に増えてしまう傾向にある。