読者です 読者をやめる 読者になる 読者になる

the sea of fertility

C#er blog - http://ugaya40.net より移転。今度のブログは落ちない

MOVEは望まれなかった子

MVC 移管記事

この記事は2012/7/14に旧ブログ(http://ugaya40.net)に投稿した記事を私の旧ブログ閉鎖に伴い移管したものです。

なにやらMOVEが話題です。

MVC is dead, it’s time to MOVE on.

http://cirw.in/blog/time-to-move-on

[翻訳]MVCは死んだ。MOVEするときがきた

きしだのはてな

http://d.hatena.ne.jp/nowokay/20120704

Twitterで「”MOVEは生まれた瞬間死んだ” って記事まだー?」って騒いでたら「お前が書けよ」の流れだったので息抜きに書きます。息抜きなので図が無いのは勘弁してください。

 

MOVEが生まれていない理由

この文中ではMOVEが生まれた理由はMVCの問題点に関わるとされており、そのMVCの問題点としてされているのは次の2点です。

  • MVCではControllerが肥大化する
  • MVCは10年古い技術で設計されていて、最新のプログラミングパラダイムに対応していない。

しかしこの理由のうちの特に上の方「MVCではControllerが肥大化する」については、非常にあちこちで見るものの、むしろそれがMVCへの不適切な理解から導き出されたずれた認識に見えます。MVCを否定する理由にはとてもあたらないどころか、この人が学んだMVCMVCではなく、MVCフレームワークの使い方であった事がよく解る一文です。

上記2点をこれから否定する事で、MOVEが生まれた理由を否定して望まれなかった子にします。

 

MVCはそもそも何をもって開発に寄与するのか

日本ではMVCPresentationDomainSeparation(以後PDS)がセットで語られることがほとんどないように思えます。しかし本来MVCPDSとセットで語られるべきものですし、そもそもMVC系はことごとく「PDSを実現する事で適切な関心の分離と責務の分割が行え、OOPの一般的なメリットを引き出す」ためのものです。

PresentationDomainSeparationとは?

PDSはアプリケーションをPresentationとそれ以外(DomainModelとかじゃないからね、ここ大事)の部分に分割しようとする基本的な考え方の事です。

PresentationDomainSeparation

Martin Fowler

http://martinfowler.com/bliki/PresentationDomainSeparation.html

プレゼンテーションとドメインの分離

Martin Fowler’s Bliki in Japanese

http://capsctrl.que.jp/kdmsnr/wiki/bliki/?PresentationDomainSeparation

そもそもドメインとはなんでしょうか?問題領域?そもそもアプリケーションは何かのドメイン(問題領域)に対するソリューションでは?

ビジネスロジックとデータ?例えばクラサバリッチクライアントのクライアントにはビジネスロジックなんて存在しませんし、そもそもクライアントのドメイン(問題領域)はプレゼンテーションです。

アプリケーションはそもそもドメイン(問題領域)に対するソリューションである。そしてそのうちの一部分をPresentationPlatformが便利に担ってくれている。しかし便利に担ってくれている分、プレゼンテーションプラットフォームは固有の知識や事情を必要とする部分がある。そこを分離する。それがPDSです。

PDSの説明にはMVCについてこう書いてあります。

This principle is the most prominent part of Model View Controller (MVC), indeed for many people MVC is how they describe this separation.

PresentationDomainSeparation – Martin Fowler

この原則は、モデル・ビュー・コントローラー(MVC)の最も有名な個所です。確かに、多くのひとにとってMVCとは、この分断をどのように行うかというものとなっています。

プレゼンテーションとドメインの分離 – MartinFowler’s Bliki in Japanse

そうです。そもそもMVCPDSを実現する手段です。

MVCPDSを実現するための手段としてもう一度考えてみましょう。MVC系をPDSから考える場合、対象とするプラットフォームはViewをDSL(RoRのViewテンプレート,ASP.NET MVCのRazorなど)で記述するプレゼンテーションプラットフォームを考えた方がわかりよいです。

PDSからMVCを簡単に導出していきます。

View + Controller(MVPならPresenter,MVVMならViewModel)の責務

まずはシンプルにPresentation側を考えてみましょう。

これはPresentationPlatform固有の知識を必要とする部分だと定義できます。

PDSをなぜするのか、その大きな理由の一つに「Presentation部分は、それ以外の部分と別の知識がなければ開発ができない(あるいは大変困難である)」というものがあげられます。ViewにDSLが存在するプラットフォームを想像しているなら簡単にわかる事です。Rubyが書けてもViewテンプレートの書き方がわからなければRoRでアプリケーションは作れませんし、C#/VB.NETが書けてもRazorがわからなければASP.NET MVCアプリケーションは作れません。

ですので、まずこの別の知識が必要な部分をPresentation側として責務定義します。

Viewの責務

ViewがDSLを使用している場合、ViewのDSLファイル・クラス自身とそれを補完する要素の事です。重要な事ですがViewがDSLを使用する場合、そもそもViewのDSLは1ページの範囲の事にしか関知しません。その各1ページの範囲の事を担当するのがこの責務です。

Controllerの責務

この責務を「ViewとModelの橋渡しをする責務」と書いてある説明は非常に多いですが最低の説明です。3つ責務があったら真ん中の責務は橋渡しをするに決まっているじゃないですか。Presentation側のうち、Viewがまかなえない責務、つまりは1ページの範囲で賄われないPresentationPlatformに関連する処理を扱います。

それがWebアプリケーションであるならば、代表的なそれは遷移の管理などです。遷移はまぎれもなくそのWebアプリケーションプラットフォームの事情でありながら(つまりはWebアプリケーションプラットフォームとしての機能を使用する)、ViewのDSLで記述する事ができません。

Modelの責務

Modelはそれ以外の部分です。PDSでDomainにあたる部分です。すなわちアプリケーションのプレゼンテーションプラットフォーム固有の知識を必要としない領域全てです。

Modelの責務にまつわる誤解

ModelはDomainModelだとは限りません(むしろWebアプリケーションでModelがDomainModelを採用する事は少ないのではないでしょうか。だいたいTrasactionScriptベースでしょ)し、DomainModelを内包しうる要素なだけです。DomainModelやTransactionScriptというのはPDSがそもそも関知しない領域 – Domain/Modelの中の設計パターンの言葉です。

決してデータの入れ物ではありません。データを入れ物にいれるのもModelの役割です。ここをカン違いするとControllerが肥大化します。Contollerがデータを入れ物にいれる役割をするとしたら、せっかくのPDSが崩れてしまうではないですか。

しかしRailsASP.NET MVCもそうですが、適切にPDSを適用する事もできるのに、そうではないように使用しやすい機能もあり、また小規模で適切にPDSを適用する事は結局PDSを崩す事にもなるため、サンプルコードから学ぼうとし、よく解っていない癖に理解したフリをした人たちが誤解を広げていきました。Controllerを橋渡しなどというのはまさに彼らの苦し紛れです。

MVCを理解せずにMVCフレームワークをつかおうとした結果でしかないんですよ。

Controllerの肥大化

PDSを適切に適用しようとすれば、まずどこに入れるかわからなくなるようなコードを挿入する場所の候補として上がるのはView(ViewのDSLを補完可能な仕組みがある場合)かModelです。WebアプリケーションではViewに機能を補完する事のできるコントロールなんてものはない事が多いのでそれはほとんどの場合Modelでしょう。Controller(あるいはPresenter/ViewModel)は、あくまでもViewの都合に引っ張られる部分であり、ここにプレゼンテーションの事情以外のコードを入れる事はPDSを崩すことになります。そうなってContollerがプレゼンテーションの事情とそれ以外の部分が混在するようになり、肥大化すればMVC系を適用した意味がありません。

というわけで、MVCで「Controllerが肥大化する問題」とか言っているのはMVC自体への不理解なんですね。

このMOVEが前提としているMVCにはPDSの視点が欠けすぎです。そして代替提案であるMOVEは、PDSを意識しないでMVC的な実装をほじくり返した結果にしか見えません。

monoの怖い先輩が教えてくれたんですが、やっぱり英語でも「お前のContollerが大きすぎるのならModelに追い出せ」という突っこみはMOVE記事に入っているみたいですよ。

Railsとかに関してもここら辺にまつわる議論はあったようです。

Ruby on Railsの「えせMVC」の弊害

Life is beautifull

http://satoshi.blogs.com/life/2009/10/rails_mvc.html

この記事自体もそうですが、yuguiさんのコメントもよく読んでみてくださいな。

ここに書いたような話は詳しくはこちらの資料に僕も書いています。こちらはWPF/Silverlightから始まったリッチクライアント用のMVC系パターンであるMVVMパターン(僕の専門です)を導出しながらMVC系のGUIアーキテクチャパターンについて説明する内容ですが基本は同じです。


MVVMの概念まとめ - the sea of fertility

 

プログラミングパラダイムの変化はMVCを否定するか

MOVE誕生の理由としてあげられていたもう一つ、MVCは最新のプログラミングパラダイムに対応していないという説明。

いずれプログラミングパラダイムの変化がアプリケーションの責務分割なんていう概念やViewのDSLなんていう概念を吹き飛ばす日がくるかもしれません。そうした時にはMVCはもしかしたら古い考え方になるかもしれません(個人的にはそうは思っていませんが)。

しかし現状の関数型ではOOP的な責務分割の仕方の否定まではいかない(関数型に対してろくな知識がないんですがScalaとかの世界でOOPと関数型をどう折り合いをつけるかの議論があるのは知っています)ように思えますし、依然プレゼンテーションの実装には固有の知識を必要としています。

そうであるかぎり、PDSは必要な概念ですし、PDSの実現手段としてのMVC系は当分滅びることがないのではないでしょうか。現状はまったく滅んでいません。多少その中身が変わったとしても、MVCが同じ概念を有したまま実装だけが進化するだけです。そして何よりもMOVEには責務分割の指針とした根拠が示されていません。MVC系の場合それはPDSと各プレゼンプラットフォームの事情です。

 

というわけでMOVEは望まれない子なんじゃないかな。