datchの日記

気がついたら社会人。気になる技術的なことについて少しずつ書いていけたらと思っております。

【デザインパターン】コンパウンドパターン【MVC】

家の中のコバエをすべて駆逐したい。

参考書



さらっと読める「OREILLY Head First デザインパターン」を参考にしながら書いています。
しばらくはこいつを参考にデザインパターンについて書いていくよ!

前回までの確認



【デザインパターン】コンパウンドパターン【事前学習編2】 - datchの日記
以前習った様々なデザインパターン

  1. Adapter
  2. Decorator
  3. Factory(AbstractFactory)
  4. Composite
  5. Observer

これら駆使して、鴨シミュレータを作成した。
そして、今回でMVCについて学ぶことに触れた。

MVCとは?



MVCはおおまかに以下のような3つの構造に分割する事が出来ます。

  • ユーザに整形した情報を表示するView
  • ユーザからの入力をView/Modelに情報を加工して通知するController
  • Controllerからの依頼を受けて処理を行うロジックの部分を受け持つModel

これらの機能はお互いの細かな状態を逐一知る必要がなく、Viewを通してユーザから何かしらのアクションがあった場合に一連の処理を行うモデルとなっている。

Wikipediaさんも参照。

MVC(Model View Controller モデル・ビュー・コントローラ)は、ユーザーインタフェースをもつアプリケーションソフトウェアを実装するためのデザインパターンである。
アプリケーションソフトウェアの内部データを、ユーザーが直接参照・編集する情報から分離する。そのためにアプリケーションソフトウェアを以下の3つの部分に分割する。

  1. model: アプリケーションデータ、ビジネスルール、ロジック、関数
  2. view: グラフや図などの任意の情報表現
  3. controller: 入力を受け取りmodelとviewへの命令に変換する

MVCの概念図

また自分の方でも軽く触れたがMVCデザインパターンではなく、デザインパターンの集合体であり、ソフトウェアアーキテクチャの1種である。
Wikipediaさんにもこのように記されている。

MVCは、デザインパターンの1種と扱われる場合もあるが(MVCパターンと呼称される)、MVC自体が他の小さなデザインパターン(Observer パターン・Command パターン・Factory Method パターン・Facade パターンなど)を利用して実装されることが多いところからすると、デザインパターンというより、さらに粒度の大きい1種のソフトウェアアーキテクチャという方が適当であろう[7][10]。
各モジュールが比較的はっきりと分かれ、プログラムの見通しがよくなるとともに、ユーザインタフェース (UI) 部分を別のモジュールに取り替えることが容易となるのが利点である。自動プログラミングなどにも適している。

昨今、Webソフトウェア開発のフレームワークとして多く採用されているMVCではあるが、ここで違和感を感じた人も少なく無いでしょう。
WebフレームワークではModelの変更がObserverパターンを使用して、Viewに直接伝えられるわけではなくControllerを介して伝搬されるからだ。
何故ならWeb開発で使われているMVCは「モデル2」と呼ばれるMVCを改良したアーキテクチャだからです。
それについては下記で説明していきたいと思います。

MVCのメリット


  • モジュール毎の依存性が低くなり、一部を修正をすることで既存のコードを大きく変更する必要性がなくなる
  • Model/View/Controllerという分割をすることで、凝集度が高くなり機能の移植が楽に行える
  • デザインとロジックの分離ができることで、平行して開発をすることが出来るようになり、デザイン/ロジックの変更が片方に波及することがなくなる
  • パターンとして役割を分割しているので、可読性が向上し、保守・管理性が向上する

などなど、様々な恩恵を受けることが出来る。

MVCの動作手順



これまたWikipedia大先生の引用になってしまうのだが、MVCは以下のような手順で動作を行う。

MVCの実装はさまざまであるが、制御フローは一般的に次のようになる。

  1. ユーザがユーザインタフェースを通してviewに入力する(ボタンを押すなど)。
  2. controllerがviewからの入力イベントを処理する。controllerは登録されているイベントハンドラやコールバックを通して呼ばれることが多い。
  3. controllerがユーザのアクションに応じてmodelのメソッドを呼ぶ。その結果modelのデータが書き換えられることもある[9]。
  4. viewがmodelから関連するデータを取得し、出力を更新する。
  5. viewがユーザの次の操作を待つ。始めに戻って、新しいサイクルに入る。

クライアントサイドMVC



参考書のMVCでは以下の概念図を元にしてMVCを実現しています。
引用元:Stack Overflow
http://i.stack.imgur.com/gBfe7.jpg

  • Model : Observerパターン
  • View : Strategy,Compositeパターン
  • Controller : Strategy

上記のMVCの動作手順でも示したとおり、

  1. ViewにStrategyパターンを使って参照されているControllerがユーザのリクエストを受け取り
  2. ControllerがModelに対してリクエストを投げ
  3. Modelの情報が変更されたことをObserverを使って通知
  4. 通知を受け取ったViewが下位の表示オブジェクトにCompositeパターンを使って、伝搬させていく

サーバサイドMVC



さて、この手順をサーバサイドで実現しようとした時、一つの問題が発生しました。
それは、HTTPはステートレスなやりとりを行うプロトコルなので、Modelの状態が初期化されてしまうということです。
また、ClientのViewの状態をModelから直接変更することは出来ません。
なぜなら、HTTP通信ではHTTP responseとしてView(この場合はHTML/CSS)を渡すことでしか状態の更新が行えないからです。
これにより、「モデル2」というMVCをWeb用に改良したパターンが考えだされました。
http://images.slideplayer.us/4/1412904/slides/slide_24.jpg
これはJavaを例に出しているので、途中でBeanなどという文字が見えるが変わったのは、
ModelからView側に直接データのやり取りが出来ないようになっている点だけだ。
逆のパターン(ViewからModelへの依頼)は従来通り可能です。

現在のMVCの利用のされ方についてツッコミを入れている面白いスライドもあった。

現代のサーバサイドMVCにおけるControllerの肥大化について言及しているが、ここで触れているMVCの原点が参考書や今回の記事でも触れているので理解も出来るでしょう。

最後に



本当はソースコードも載せようと思ったのだが、Viewが出てきた時点でJavaのSwingが出てきたり、
Webアプリケーションにおいてはサーブレットなどのコードが出てきてしまい、MVCについて学習するという本質からやや離れてしまう可能性を危惧し、今回はソースコードを書かないことにした。
自分たちが触れているControllerの使い方に関して、間違っているという指摘もあり、MVCについて色々と考えさせられる学習内容になった。
どのように書いていけば、簡潔にコードを書けるようになるかを考えながら、これからもMVCと仲良くしていきたいと思う。