MVCについて (1)

自分にはプログラムは書けないと遠い昔に思っていたが、稚拙ながらなんとか書けるようになった。そう思わせてくれたのはJavaだったが、今ではRuby言語やAS3言語たちと遊んだりしている。

MVCとの出会い

そうしたアプリケーションの楽な作り方があったら知りたい、という気持ちがあった。基本的に、これらの言語で何を作ろうとしても、作法はあるのではないか。そうして出会ったのはMVCという概念だった。MVCについて学ぶ必然性を与えてくれたのがRuby on Railsで、より積極的に学んだのはPureMVCやrobotlegsというMVCフレームワークだった。

MVCというのは、GUI(グラフィカルアプリケーション)の制作において、有用な形だ。これを使うことで、複雑なアプリケーションのスパゲッティが、少しは食べられるものになる。

だけれども、MVCのことを知らないで、ほかの人が作ったMVCアプリケーションのソースコードを見たときは、スパゲッティ以上に意味の分からない何かに見えた。経験的には、MVC適用を厳格にしなかったプログラムをMVCに書き換えた際には意味が分からなくなった、という意見をもらったことがある(大方、書き方が悪いのだろうけれども)。概念を知っていないとMVCフレームワークの読み込みは非常につらいものになるのかもしれない。

MVCの概念

MVCは、ものすごく単純には、プログラムのソースコードの中のディレクトリを3つに分けましょう、ということだ。その3つとは、View(見えるもの)、Model(データ)、Controller(操作するもの)のこと。WPFで言うところのXAMLやJAVAのswing、FlexのMXMLにあたる部分はViewに入る。それ以外のロジックはそれぞれModel,Controllerに入る、という感じだ。

まず始めにMVC的にプログラムを書くぞー、というときにはこんな風に適当に分けた。こうして分けようとすると、ModelとViewはなんとなく分かるけれどControllerとは何ぞ?ロジック書けばいいの?という気分になっていく。

MとVとCの関係

ユーザの操作の流れからすると、MVC内ではこんな風な流れ作業になる。

ユーザからの操作をControllerが受信する。ControllerはModelを叩いて値を変更する。Modelの値の変化をViewは監視していて、変化したことを察知したのでViewの値を変更する。

この図を見ていると、「ユーザーの操作が直接Controllerに入るのはおかしいじゃないか。だって、ユーザーの操作はビュー上の部品から行われるだろ?」という気分に襲われなかっただろうか。「いや、ジョイパッドのときはビュー関係ないだろ?」という意見もあるかもしれない。

View上の部品に対してユーザーが何かをした場合は、その部品からControllerにこっそりユーザーが何かした、ということを教える。その方がコードが分かりやすい。また、モデルの値が変化したときにも、Viewに対して”変化した”ということを教えなければなるまい。

つまり、このようなこっそり教える関係性がある。実はこれがイベント駆動とかイベントドリブンだとか、GUIアプリケーションの一番初めにぶつかる概念のイベントの伝播だったりする。

Modelの値の変化は必ずしもControllerが始点ではなくてもよくて、例えばTimerだったり、他のサービスへのPollingだったりが、そうしたものだ。そのために、Modelの変更をViewが見守るという関係であったりする。

MとVとCの関係度

で、コードを書くときに気になるのは、コードの使いまわし(GUIをCUIにしろ)だとか、コードの保守性(簡単に見通せて変更ができるか)だったりするのだが、一般にMVCは以下のような依存を持つとされている。


Controllerを変更してもViewとModelは大丈夫。Viewを変更したら、Controllerを変更しなければならないかもしれない。Modelを変更したらControllerとViewの両方を変更しなければならないかもしれない。そんな感じ。

特に大変なのは、Modelを交換したときで、ControllerとViewの2つの面倒を見なければならない。だから、Modelは最初にがっちりさせておく。まさに太らせる。Fat Model。Controllerを太らせてはいけない。Controllerは基本、使い捨てだから。

で、どんなViewを作ろうとしても、Modelの値の引き方というものはModel固有のものになってしまうので、ModelごとにViewを作り込むという結果になってしまう。依存度高し。

このViewのModelへの依存度を減らそうという考え方がある。

いつか書けるといいなリスト

・依存度を減らそうという考え方の話
・カチコチなMVCって何なのさ的な話
・規約なMVCってどんな感じな話

「MVCについて (1)」への3件のフィードバック

  1. 「この図を見ていると、『ユーザーの操作が直接Controllerに入るのはおかしいじゃないか。だって、ユーザーの操作はビュー上の部品から行われるだろ?』(中略)View上の部品に対してユーザーが何かをした場合は、その部品からControllerにこっそりユーザーが何かした、ということを教える。」
    という部分ですが、SmalltalkのMVCではユーザの入力はViewを通さずに直接Controllerが処理します。

    InputSensorというクラスがあり、そのインスタンスが現在のマウスの状態や、キーボード入力のキューを持っています。
    ControllerはループをまわしながらInputSensorを調べて変化があれば処理(モデルのメソッドの呼び出し)します。

    モデルは自身が変化するとViewなどに通知を送ります。
    Viewはモデルの状態を調べ、画面を表すDisplayScreenに図形を描きます。

    (Squeakのソースと次の文献を読んだだけなので、昔のSmalltalk-80では詳細は違うかもしれません)
    Applications Programming in Smalltalk-80(TM): How to use Model-View-Controller (MVC)
    http://st-www.cs.illinois.edu/users/smarch/st-docs/mvc.html

  2. るとさんへ、

    はじめまして、コメントありがとうございます。
    自分はSmalltalkについてMVCの祖であることまでしか知らず、Smalltalkについてどの文献を見ればよいのか分からなかったので、SmalltalkのURLの内容は非常に参考になります。

    Controllerがキーボードやマウスの入力をまとめているのですね。そのような仕組みだと、Viewのどの部品が押されたのか判別できるのかな?と思いましたが、Viewの部品ごとにそのViewのための個別のControllerへの参照を持つので、行うべきmodelへの処理が自明なんですね。(と、調べた範囲では理解しました)

    となると、ViewはControllerの参照を持つので、SmalltalkのMVCにおいてViewはControllerに依存することになりますね。M-VCという言葉があるのもうなづけるような気がします。

    自分がWebで調べたMVCは、Smalltalkの時代のものとは概念は同じようなものでも、内容に違いはあるんだなぁ、と勉強になりました。MVCの根幹?であるModelからViewへ更新を通知するObserverパターンは、Smalltalkのdependencyメカニズムとして同じもののようだったので安心しました。

    自分自身MVCについての理解に不安がありましたので助かりました。また何かありましたら教えてください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください