MVCについて (3)

厳密なMVCについて書こうかと思ったが、そもそも厳密なMVCはSmallTalkのMVCで自分はそれを知らない、ということに気がついた。つまり、MVCと名前の付く派生としてはrobotlegsとPureMVCくらいしか知らないので、自分の解釈は間違っているのかもしれない、という不安はある。よって、今回の話はそれらの派生MVCの話として、話半分に読んでほしい。

前回はMediatorがMVCとMCVの明暗を分けるとか何とか。Mediatorについては、MVCの細かい機能分けの話が絡むので、今回の話で。

厳密なMVCの機能分け

MVCは制約をつけること(例えばpublicやprivate)で、誰もがわかりやすくて保守性の高いプログラムを書きましょう、という認識を持っている。これは、つまり、Model層、Controller層、View層に分けるということだ。

MVCをもっと仕分けすると色々出てくる。2位じゃいけないんですか?
・Controller
 ・Command
・Model
 ・Proxy
 ・Service
 ・Delegate
 ・VO
・View
 ・Component, UI
 ・Mediator
このほかに
・Event
・Facade
あたりがその辺をうろつく。

これらの機能分けについて説明していく。MCVではなくMVC的な説明になるのでよろしく。

それぞれの役割

Component, UI

最近のIDE(統合開発環境)では、GUIもコピペーで簡単に構成することができる。これぞデザイナー向き機能。コピペーで作られた画面というものは、XML系(MXML,XAML)だったり、バイナリ系だったり。基本的には、プログラムコードは混入しない方がデザイナーに壊されないので都合が良い。

多少複雑な部品だと、それ1つでMVCの系を持っていたりする。自身で完結するMVCを持つなんてComponentくらいのもの。小さな宇宙。一見、FlexやC#なんぞに触れると一番お世話になる部分だったりする。それがComponent。

Mediatorさん

インターフェースをまとめる。

Componentにコード書きたくないので、代わりに必要な人。Viewに関わる色々なことをする。Viewで完結する(ControllerとModelが関係ない)ような動作はMediator内に収めた方がいい(ような気がする)。

あとは、Modelの値が変わった場合に監視する役もMediator。どの値を見に行くの?みたいな。Viewが叩かれてControllerにチクりにいくのもMediator。つまり、UI Componentに直接さわらせないぞ、という役の人がMediatorさん。

Commandさん

Controllerさんのお仕事。一連の作業に名前をつけてまとめる。

叩くのは、主にModelさん。Modelさんのインターフェースをどんな風に叩くのか、どんな順番で叩くのかを持つ。

時に大事な仕事は、外部のサービスから取得したデータをModel(メモリ空間、もしくはDB)に格納するとき。Model(Service)でデータを取得したときにイベント箱が届けられるのだが、その箱の中のデータを別のModel(Proxy)に入れたりする簡単なお仕事です。

Modelさんがメタボになると仕事が無くなる。というか、だんだんControllerって自動生成でいいんじゃね?という気分になってくる。でもModelとModelの橋渡しをするときには必要な人。

VOさん

ValueObjectの略。なぜか略されることが多い。

構造体のクラスバージョン。入れ物だけ用意。時々仕事するけれど、VOのメソッドで自身が変化するのはNG。変化したい場合は、分身してください。

Modelさんと、Eventさんの持ち物であるが、時にMediatorさんが開けることもある。

Proxyさん、Serviceさん、Delegateさん

この3つの呼ばれ方をするModelが多い。

Proxyさんは代理人さん。Mediatorさんも代理人さんっぽいけれど、Proxyさんの名前がつくと主にModelの仕事に就くことが多い。この3つの呼び名は、外部のサービスを呼ぶModelの名前。例えばFlickrService.getFlickr(keyword)とかメソッドが存在すると、ちょっとFlickrまで行ってくる…という作業を行う。Flickrからブツを持って帰ってくると、イベント投げてCommandを発令して、仕事は終わる。

失敗すると、Mediatorに「失敗したよ!てへ☆」といって死ぬ。市

外部にクエリを投げないModelさんは、素直にModelさんと呼ぶことが多い。そういうModelさんはVOをたくさん持っている。

Event箱

箱にしたくない箱。夢と希望と絶望が詰まってる。MVCのそれぞれをつなぐ線。

MediatorやModelの中にはEventDispatcherさん(イヴェントディスパッチャ・タイ人か?)という人がいる。この人がEvent箱を川にぶん投げる。

Facadeさん

ModelとControllerとViewの管理者。

EventDispatcherさんがぶん投げたEvent箱を、郵便局勤務10年の手さばきのごとく、パスする。Serviceの例だと、Flickrから取得が成功するとFlickrEvent.成功したよ、が帰ってくるが、それをShowPicturesCommandに投げる。ここで、投げるリストに登録しなくて、動かなくて涙目になることがある。

概観

順番的には、以下の感じ。

ユーザ操作で外部APIを叩く

Mediatorさん→EventDispatcherさん→Facadeさん→Commandさん→Modelさん(ユーザ操作)

(1)ユーザ操作がUIからMediatorに伝わり、MediatorはFacadeに投げる
(2)FacadeはEvent内容を見てCommandに投げる
(3)CommandはModel[Service]を操作する(外部サービスからのデータ取得を依頼する)

外部APIの結果を格納する

Modelさん→EventDispatcherさん→Facadeさん→Commandさん→Modelさん(外部からデータ取得)

(1)Model[Service]が取得した結果をFacadeへ
(2)FacadeはEvent内容に応じて指定のCommandに渡す
(3)CommandはModelを変化させる(取得した結果の格納を依頼)

外部APIの結果を表示する

Modelさん→Mediatorさん(値変更によるView変化)

(1)(結果の格納によって)ModelがMediatorに値が変わったことを教えて
(2)MediatorがModelに値をとりにいく

ちなみにユーザ操作で直接Modelの書き換えもあり。単純なので今回は略。

Mediatorのお仕事

ということで、UIとその他Controller, Modelとの橋渡しを行うのがMediatorなのだが、この仕事はM=C=V形式のCの仕事に該当するような気がしてならない。

今回のフレームワークではCommandは一連の作業を行うデザインパターンであるが、この作業は実はModel内のビジネスロジックに含まれるべきもので、実質はModel間のデータ受け渡しくらいしかControllerはすることがない(ような気がする)。このデータの受け渡しは、Model間の依存関係を気にしなければ、Model組み込みで行ってもかまわない。そうなると、ほとんどContollerはする仕事がない。

ということで、Controllerには他の仕事をさせないで、Controller≒Mediatorという扱いにしたのがMCVなのだろうかなぁという印象がある。

というところまでが、今回のMVCについての話。余力があったら、CoCとMVCの関係について書くかも。

カテゴリー: チラシの裏 パーマリンク

コメントを残す

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

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