MVCの適用限界について考えることをテーマにして書き続けてきたが、MVCとその変遷が複雑すぎて、それらを考察し終えるのにはまだまだ時間がかかりそうである。
なので、一旦、現時点での筆者のMVCの適用限界に関する見解をまとめることにした。
ここでは、ドメインモデルとビジネスモデルをまとめて「ビジネスロジック」と表現する。以下の「ビジネスロジック」は「ドメインモデル」に置き換えても同様である。
●1. MVCパターンは、現代のGUIフレームワークには適さない
ウィンドウやウィジェットを入れ子構造で配置し、ボタンやリストなどの表示部品を置き、それらが押された時の動作などを各表示部品に直接関連付け、マウス操作などのイベントがアクティブな子ウィジェットから親ウィンドウへと伝搬される、AWTやSwingや*/TkやGTKやVBやVCなど、現在開発に使用されている代表的なGUIフレームワークでは、MVCで言う所のControllerが階層構造のViewに分散しており、ControllerはViewの一部という形になる。それにより、ControllerがViewに依存する形となり、例えば、CをそのままにしてVを追加/変更できるという前提が崩れる。
いわゆるGoF本に書かれているMVCでは、originalの(Smalltalkの)MVCとは異なり、ControllerはViewの一部だと割り切り、presentation logicとdomain modelを分けて多対1の関係とすることに絞っている為、現代的なGUIフレームワークにも適した考え方となっているが、それはMとVだけで成り立つ概念であり、MVCと呼ぶ意味が無いものである。
なお、MVCはGoF本の発刊時点で既にこの理由でobsoletedであった為、デザインパターンの元祖として紹介するだけで、同書の23のデザインパターンとは並列にされなかったという説もある。
これに関して、参考リンクに挙げたWebページから、いくつか興味を引かれた文章を引用する。
[3]のコメント欄より:
if you need to send an onMouseOver event to a controller instead of just changing state on the button in the view, what do you gain?
...
Only things that change application states (be they persistent, session-specific, or application-wide) should be sent to a controller
(Viewしかわからない)MouseOverイベントをControllerが受けてViewに配送することに何の意味があるのか?(Viewが単独で処理すれば良いのではないか?)という疑問である。Modelの変更に繋がり得るイベントだけがControllerを通れば良い、というのも同感で、そこまできちっとViewからControllerを切り離す必要性は無いと思う。
[6]のコメント欄より:
MVC, and StateMachines are orthogonal concerns (depending on the app each tier may have it's own StateMachine). The differentiation typically is in MVC the model state is persistent, and survives a many to one relationship (e.g. a bar and line graph both using the same data.) where as state machines are useful for runtime states.
MVCと状態遷移モデルは直交する概念で、状態遷移モデルの状態は全てMVCのModelの状態であるべきだということにはならず、永続的でV-Cとは多対一の対応の関係にあるものがModelの状態であり、ViewやControllerがそれぞれ実行中の状態(及び遷移モデル)を持っていても良い。
GUIフレームワークでは、Viewの状態とControllerの状態が分離されない(全て同じ箇所に書けてしまう)ので、意識的に努めて行わない限りは、ViewとControllerが分離されない。というか、現実的には(単純な例題でもない限り)ViewとControllerとの状態の分離はやり切れないと筆者は思う。
同じく[6]のコメント欄より:
Some definitions of MVC call for a single controller, supporting multiple models, each with a view. Obviously, Flash apps almost never work like that - Flash MVC is really distributed MVC, often different views have their own controllers, and views are all managed by a master state management controller.
Adobe FlashのアプリをMVCに当てはめると、M:V:Cの関係が通常の多対多対1の関係ではなく、ViewはそれぞれControllerを持ち、それとは別の巨大なControllerによって制御される、"distributed MVC"である。
なお、Cocoa MVCでは、"Responder"(Controllerへの参照のようなもの)と"Responder chain"(イベントを処理できるハンドラーの検索順序を決めるリスト)という概念によってGUIフレームワークとMVCとを整合させているそうだが、本当にこれによってControllerがViewの構造とは独立の構造を持ち、例えばViewだけが交換可能になるのかどうかは、筆者にはよくわからなかった。(View毎にResponder chainを用意するというのは、View毎にControllerの構造を用意するというのと同じようなものなのでは...)
●2. MVCパターンは、リッチなクライアントを持つWebシステムには適さない
本来、MVCパターンでは、Modelが変化すればViewがその通知を受けて、ViewがModelの状態を取得して表示に反映するものであるが、通常使われるHTTPのような(PUSH型でなく)PULL型の通信手段を使用しているWebシステムでは、Modelの本体がサーバー側、Viewの本体がクライアント側にあるので、Modelの変化に伴ってViewを更新することができない。
Webシステムでよく使用される、J2EEやStrutsやFlexのような、いわゆる"Model 2"のフレームワークでは、サーバー側の構成にMVCパターンの考え方が採用されており、WebシステムでMVCと言えば大体これのことを指す。しかし、クライアント側も含めてMVCパターンにすることをサポートするフレームワークは存在しない。
"Model 2"でも、サーバー側、クライアント側それぞれ別々にMVCパターンを適用することは可能であるが、それはアプリケーションのGUIのみをMVCにするようなものなので、クライアント側をMVCにするメリットは少ない。
クライアント側がHTMLを表示するだけのViewの機能と、HTMLブラウザの機能だけで実現できるフォームやボタン程度のUIであれば、クライアントはViewのみとしてもまず問題にはならないが、AjaxやFlashを用いるなどして、クライアント側のUIをリッチにすることが可能になり、例えばユーザーの入力にリアルタイムに反応してボタンの有効状態が変わるようにしようとすると、それによってボタンが有効になるべきかどうかをキーストロークの度にいちいちサーバー側に問い合わせるか、Modelに相当するビジネスロジックをクライアント側にも含める必要が出てくる。
このような問題をまともにMVCパターンで解決するには、Webシステム全体としての機能をMVCに分割し、Model, Controllerそれぞれをサーバー側とクライアント側に配置し、Model同士、Controller同士がそれぞれ最小の通信量で済むように協調動作することが必要になる。それ自体が容易でないのに加えて、そういう構成をサポートするMVCフレームワークは現存せず、それに既存の"Model 2"のMVCフレームワークが使えないので、サーバー側とクライアント側を合わせてMVCパターンにすることは困難であろう。
ついでに言うと、"Model 2"のMVCと本来のMVCは異なるので、Webシステムで本来のMVCパターンを取り入れようとすると混乱が起こるのではないだろうか。
参考リンクからいくつか引用する。
[1] "MVC As Anti-Pattern"より:
But what if you are building a web application with a rich client?
[snip]
Do you still need an MVC framework?
I think the answer is most likely no.
このページ全体がこのテーマで、論旨がよくまとめられているので、興味のある方は是非読んで頂きたい。
Developers who use modern rich-client frameworks do not have to create controllers to manage events. What a runtime and its frameworks do internally is a different story.
この"rich-client frameworks"は、View内の構成要素それぞれがController(イベントハンドラー)を備える、通常のGUIフレームワークのことを指す。
[3]より:
I've come to the conclusion that... drumroll please... MVC is probably not needed for most RIAs.
RIAはRich Internet Applicationsの略で、クライアント側もリッチなアプリケーションであることを意味しており、この記事の所々にある"FrontController pattern"は、その対極に、クライアント側はシンプルで、何もかもサーバー側のFrontControllerを経由する構成のことを意味している。
You often see architectures in which a single controller handles all of the "actions" for the entire application. I see this as a necessary evil, not a "good thing". The world of the giant switch statement is exactly what we wanted to avoid with OO programming, right?
ここでは、MVCのControllerは巨大なswitch文の塊になりがちであることが問題にされている。例のmost controversialなSkinny Controller, Fat Modelと同時期に呈された、MVCに対する不満である。
[3]のコメント欄より:
I agree, separate model and view is enough, controller sometime is abused
M-Vの分離には意味があるが、Cの分離はえてしてやり過ぎである。
[6]より:
Fact: No one codes Flash using pure MVC.
このページに書かれているのは主に一般論だが、なかなか深く鋭い話で、一読に値すると思う。
[3]のコメント欄より:
In addition, just consider the case (in the real Business world) when you need to deploy a program (which also holds the Controlling) on the client machine
クライアント側にView以外のロジック(ビジネスロジックそのものや、サーバー側のビジネスロジックを扱うController)を含めることについての問題提起であり、一般にクライアント側でのプログラムの実行は難しいので、故にV-Cの分離は重要だと述べられている。確かに考慮すべき事柄ではあり、V-Cの分離が現実的に可能であれば一理あるが、実際にはV-Cの分離に労力を掛けるより、クライアント側でプログラムを実行することに労力を費やす方が、コストが小さく、何よりも自由が利くので、労力に見合うのではないだろうか。
[3]のコメント欄より:
Anyone who justifies MVC as a way of making a web app "like" a desktop application's MVC architecture is fooling themselves. The internet just doesn't work that way. I've seen IT budgets balloon and schedules run late because of the blind, over-zealous switch to MVC, while chanting "industry standard" to anyone who asks "why?"
●3. MVCパターンは、リッチなGUIには向かない
MVCパターンでは、UIの制御は、必要であればViewに(カーソル位置、スクロール位置等の)表示状態を問い合わせながら、Controllerが主となって行うことになっている。それにより、ControllerはViewの画面構成に依存せず、Viewのみの交換や、表示の異なる複数のViewの追加が可能になるのである。
しかし、そのようなViewの抽象化は、全てのViewに「タイトルバー」と「メニューバー」があり、「メニューバー」は「項目」または「項目グループ」を含む、など、ある程度はUIの形状が決まっていないと困難である。
また、Viewの状態が複雑になるだけ、Controllerも複雑になる。いくら何でも、マルチウィンドウ状態を持つVを、1つのループとswitch文でなるControllerが制御するのは限界があるので、必然的にControllerは分解することになるが、その分解方法はある程度Viewの構造に依存しないと複雑になる。Viewを抽象化し切るのが困難になり、抽象化する労力が効果に釣り合わなくなるのである。ウィンドウマネージャーくらいの機能だとまだ実現可能かも知れないが(それでも相当大変だ)、クリックされた位置がどのような抽象状態の時にどうする、とか、メニュー画面がスクロール可能な場合はどうでページ送りの場合はどうで、とかいうのを、Viewを抽象化してViewがどんな形でも動けるようにするのは至難の業である。
ウィンドウシステムのあるマルチアプリ環境にMVCパターンを当てはめることを想像すると、アプリ毎にMVCがある構造を思い付くのが自然ではないだろうか。アプリの追加/削除まで考えると、仮にMはアプリケーション間で共通のものを使用できるとしても、VやCをも共通にできると思う人は居ないだろう。それができるとすれば、メニュー画面しかないアプリくらいである。つまり、アプリケーションマネージャーを除き、Viewの数だけControllerが存在すると思うのが自然である。1つのアプリケーションでも、巨大になれば構造を分解することになるが、マルチアプリ環境と同じ発想で、ViewとControllerを複数のV-Cのセットに分解する構造にすることを考えることが可能なので、それに行き着くのが自然であろう。GUIが大規模になれば、Controllerの構造がViewの構造に一致する、というより、ControllerがViewの構造に縛られるのは宿命なのである。
このことは、実はoriginal MVCでも少し触れられている。前の記事にも挙げた、"The Model-View-Controller (MVC) Its Past and Present"のP-8 "Tools for Tasks"とP-9 "Tool as a composite"がそれであり、タスク依存のV-CはToolとして独立させれば良く、ToolはToolを組み合わせて構成すれば良いということなので、これは、現在主流のGUIフレームワークを使うと自然とその形に誘導される、GUIをウィジェットの入れ子構造で実現することとほぼ同じことである。これでアプリケーション全体がToolの組み合わせだけで実現することがMVCパターンの範囲に入るなら、現在主流のGUIフレームワークはMVCパターンから逸脱していないことになるが、さすがにアプリケーションのトップレベルがMVCの構成でないのはMVCパターンとは呼べないであろう。また、通常MVCという用語が使われる時に、P-8やP-9の意味を含むことは稀である。
また、GUIが複雑になれば、GUIそのものをMVCに分ければいいという意見が出てくることもあるが、一般にV-Mが強結合だとMVCはうまくいかないことが知られているし、それこそMVCパターンを使うことが目的になり、何の為にMVCにするのかがわからなくなってしまう。
[3]のコメント欄より:
One of the reasons that people build controllers is to isolate the interaction logic from the view, with the goal of being able to swap out the view. The problem with this approach is that with the richer UI vocabulary that RIAs allow, I believe it is not possible to do this.
UIがリッチになると、UIのロジックをViewから切り離すのは不可能だと思うと書かれている。
筆者も、M,CをそのままにVだけ交換可能にするというのは、スキン(画像ファイル)の交換くらいが限界だろうと思う。GUIの見た目が変わって操作が全く同じということはほとんど無いだろう。
●4. MVCパターンは、エディターには向かない
テキストエディターや文書作成アプリや画像編集アプリなどは、MVCパターンへの当てはめ方が難しいアプリケーションの例としてよく挙げられるものである。
何をModelにするべきかという問題ではあるが、デザインパターン、つまり共通の知識としてのMVCの一般的なコンセンサスとして、Modelの状態は永続的なものであることと、ModelはViewに依存しないことがあるが、それからすると、テキストエディターのModelの責務は、文書を保存して読み出すことくらいになってしまう。
人間にわかり易い形、つまりビジュアルなデータ編集ツールの中心部を、ビジュアル抜きに形式化するのは困難である。かと言って、ビジュアルがメインのアプリケーションなら表示状態もModelに含めれば良いかというと、そもそもPresentationとModelが分離される背景には表示系はよく変更されるという前提があり、表示系が変更するとMにもVにもCにも変更が入ってしまうのでは、何の為にMとVとCとに分離するのかがわからない。
また、通常、ControllerとModelとの間のセッション状態(ひとまとまりの協調動作における状態)をModel側に持たせることは好ましくない。C-Mの関係においてはControllerが能動的、Modelが受動的に動作するので、セッションの開始と終了がわかるのはControllerだからである。例えば、テキストエディターの編集中の状態をModelに含めると、同時に編集するデータの数に比例してModelの状態が複雑になってしまう。(セッションの数だけModelのオブジェクトを作成するならさほど複雑にならないが、それはControllerがセッション管理しているのと同じことである)
Original MVCでも"THING-MODEL-VIEW-EDITOR"という分け方があるように、オブジェクトの中身を操作するUIはMVCパターンの中でも特殊な位置付けであり、"EDITOR"はMVCに当てはまらないものの代名詞とも言えるのである。
エディターの他に、MVCの適用が困難な例としては、ゲームがよく挙げられる。エディターと同様に、画面表示がメインのアプリケーションは、ModelとViewの結合が強いので、MVCの分割に向かない。また、HMI(Human-Machine Interface)や感性モデルやバーチャルリアリティーのように、変化しないModelを確立するのが難しい分野にも向かないと考えられる。現実世界のモデル、現実のビジネスモデルとHMIは追究の仕方が異なるので、開発スタイルも異なるはずである。
アプリケーション全体としては直感的にMVCに分けることができても、部分的にMVCに分けるのが困難になる例としては、Modelの実行中の確認ダイアログが有名である。
そのビジネスロジックにおいてその手順中にユーザー確認が必要であったら、その情報はModelにあるべきであるが、ダイアログ画面の表示制御はControllerの仕事である。確認ダイアログ1枚くらいなら、Modelの処理をその前後で分けて、Controllerが前半の処理とダイアログ制御と後半の処理を順に行えば簡単であるが、一連のビジネスロジックの処理中に何枚かのユーザー入力画面が必要だったり、それらが画面遷移モデルを伴ったりすると、問題は一気に複雑になる。あくまでControllerがビジネスロジックを含めない方針にすると、ModelはControllerへの応答だけで次に出す入力画面を伝える必要があり、ユーザーからの入力が不正かどうかをControllerは判断できないので、Modelは不正入力を判断して、場合によってはエラー表示を伴う異常処理を行わなければならなくなる。
ビジネスロジック固有のUIの画面遷移と、タスクやView固有のUIの画面遷移とがあり、View固有としてV-C側に置かれていた画面遷移が、Viewが増えた時にView間で共通のビジネスロジックだと決まると、Modelに移動させる必要が生じたりする。
そもそも、ビジネスロジックがUIを伴っても、その実行時の画面遷移状態はセッション状態であり、Modelの状態としてはふさわしくない。
かくして、UIを伴うビジネスロジックがControllerに置かれるようになり、Modelの存在意義が希薄になり、Controllerがビジネスロジックの塊となるのである。
これも突き詰めると、MVCでは、UIを伴う処理をModelに取り込むのは厄介だということであり、エディターがMVCに向かないのと共通点の多い問題である。
各々のプロジェクトにおいて、何をModelにするかという方針を明確にしさえすれば、そんな問題は起こらない、という意見もあるが、対象が物理モデルやH/Wでも無い限りは、どこまでをビジネスロジックと見做すのかは、それほど一意に決まらない。始めはアプリケーション固有ロジックであっても、それが再利用されるようになって初めてビジネスロジックになることも少なくない。どう考えてもpresentation logic、そのViewでしか使わない固有の処理だろうと思ったものが、実はそのビジネスモデルで共通だったというのは、よくあることである。
UI intensiveなエディターをどうMVCに分解するかというのは、SmalltalkのMVCでも同様の問題がある気がするのだが、筆者はこれについて何らかの解が示されているwebページを見た記憶が無い。筆者は、エディターからModelを迷い無く切り出せるようなModelの定義は存在しないと思っている。
参考リンクからいくつか引用する。
[2]より:
By letting the service layer refer to sessions, I am also creating a Model that is hard to test without having an entire application in place.
ここでは"service layer"はModelの上層部、ControllerやViewから直接呼び出されるI/Fを含む層を指す。Modelがセッションを参照すると、Modelを単体でテストするのが困難になる、と書かれている。
同じく[2]のコメント欄より:
This makes me think of what Misko Hevery was saying in a previous blog post - that the more testable something is, the better it is probably architected. And, the more easily tested it is, the more it likely decoupled from other objects.
One of the huge benefits of separation of concerns is testability. If you've designed your components properly, you should be able to write test cases that can give you some peace of mind.
[4]より:
If you are designing a graphics intensive program, like a game, you would probably couple the View and Model classes much more tightly than what MVC suggests. As we can see from the Basic sample application, when programming a very simple application it is common to combine the controller with the view classes.
[3]のコメント欄より:
Things, of course, get tricky when user interaction comes into play. For example, if you need to pop up an alert that asks the user a question before completing the transaction.
[3]のコメント欄より:
If you're doing a word processing application, is the keypress sent to the controller, added to the document via the model, then the view is refreshed via the controller? Or is the model used to save changed files and the view handles all the live updates to the text?
[6]より:
MVC says that the entire application state is supposed to reside in the model. However, many applications maintain application view state in the controller, and the data state in the model.
MVCではアプリケーションの状態は全てModelに置かれることになっている(Original MVCではある程度のGUIの状態はViewが保持してもいいことは省略されている)が、実際にはControllerがViewの状態を保持していることが多い、ということ。
ControllerにGUIの状態を置かないことが実際には難しいことを暗に言っていると思う。
Original MVCでControllerがViewに表示状態を問い合わせても良いと書かれているのは、当時はGUIの状態は少なく、リスト上の表示範囲やカーソル位置など、View固有の状態だけで表現できるという前提があったから、もっと言うとSmalltalkではアプリケーションの形をある程度決めることができたからそういう設計思想が通用したのであり、ボタンの状態や文字色やパネルの入れ子や不定形なGUIやフォーカスやアニメーションなど、昨今のバリエーション豊富なGUIでは、むしろModelよりも状態数が多いことも少なくない。
●5. MVCパターンは、リアルタイムなUIに向かない
これは、Viewの画面更新はModelの変更完了後になされ、ユーザー入力を受けるControllerがそのままViewの画面更新を同時に行わないことによる。
よくあるMVCの実装だと、Model-Vew間のObserver patternがきっちり作られているため、ModelとViewが非同期的に動作し、Modelに何か変化があったという通知をViewが受けて、ViewがModelに最新の状態を問い合わせるという、Model内のデータの更新と画面の更新とを同時に行うのに比べて無駄の多いシーケンスとなる。Controllerから見ると、もう画面をどう更新すればいいかがわかっていても、イベント配信のスケジューラーに任せる形で、表示更新を後回しにするしか無いことがある。
もちろん、Viewは必ず非同期に動作しないといけないということは無いので、Modelの更新中にViewに更新要求しつつ、即座にViewに実行権を明け渡すような同期処理にすることも可能だが、Modelの更新に同期して都度表示更新するのがユーザーレスポンスが再短時間になるとは限らない。すなわち、Modelの更新がある程度済んでから描画する方が速いケースも少なくない。
一続きのModelの更新が完了したタイミングがわかるのは基本的にControllerなので、必要な時はModelの更新前にViewに表示更新禁止指示を出し、Modelの更新後にViewに表示更新要求を出せば良いのだが、そのような必要が多いシステムであれば、VewをModelのObserverにする意味が無いであろう。
また、MVCパターンでは表示に関するビジネスロジックもModelにあるのが前提(Viewが交換可能なのが前提だから)なので、必然的にViewからModelへの問い合わせが増えることも考えておく必要がある。Modelへの問い合わせが、メソッドの同期呼び出し等、同じ実行コンテキスト内の同期処理であればオーバーヘッドは小さいだろうが、ViewとModelが並列動作していて排他制御が必要だったり、Modelがネットワーク越しにあったりすると、一部のビジネスロジックはViewにも含めるような、MVCパターンから外れる対策が必要になるだろう。
参考文献[5]より:
The first problem area is to deal with setting the color of the variance. This shouldn't really fit into a domain object, as the color by which we display a value isn't part of the domain.
表示する値(ここではvariance)に定性的な意味合いに基づいて色付けする場合にその色の決定処理をどこに置くかという例題で、この文章に続いて、MVCパターンにおける、表示に関するビジネスロジックの扱い方について、深く考察されている。長くなるので詳細は割愛するが、オブジェクト指向言語だとtext fieldのsubclassを作るのが好みだと書きながら、結論としてはMVCの他に"Presentation Model"(View側のビジネスロジックを含める部分)を設けることによって大抵解決できると書かれているのが興味深い。
●6. MVCは絶対的な指針にはならない
人々のMVCパターンの理解がこれほどまでにばらつく理由は、Web系のフレームワークにおいて絶対的な地位を築いた"Model 2"や、かのGoF本に書かれた技術的なロマン溢れるMVCなどの、原典であるSmalltalkのMVCからかけ離れた亜種がSmalltalkのMVCより圧倒的に有名になったことが直接の原因だと思って間違い無さそうである。そのように多種多様なMVCが生まれる原因には、それらのいずれもがMVCを誤解したものだと言われないことがあると思うし、それは、MVCに正解が存在しないからであろう。
Smalltalkの開発中に考案されたMVC理論は、複雑すぎて人々に理解されず、そして、SmalltalkのMVCは現代の進化したGUIを持つアプリケーションにそのままでは使えなくなったので、MVCの原典を繙く人が増えなかったのだと思う。
さらに、ソフトウェアの規模が大きくなったのに合わせてMVCに色々と改良が加えられても、人々が納得する決定版が現れないので、人々のMVCの理解がばらつくのを止められないのだと思う。
人々は、ある理論を理解することを放棄する時、それが全てではないでしょ、という言い訳をする傾向がある。ソフトウェア設計者は、既存の設計が理解できない時、もっとシンプルにできるはずだと言い訳して放棄する傾向がある。ことこれほど広まっているMVCパターンに限って、理解できないという言い訳は敗北と考えて、せめて割り切ってMVCと接することができるように理解に努めてきたが、筆者は、MVCの理論にも適用可能範囲にも絶対的なものは無い、つまりMVCとして絶対不可侵な範囲も無く、こういうアプリケーションに有効と言える対象も無く、ましてやどんなアプリケーションでもMVCパターンに従うべきだということは無いと確信するに至った。
MVCパターンは、ただ闇雲に何が何でもMVCにすれば良いものではない。理論を知らなくても、忠実に守っていれば何かご利益があるような便利な知識ではなく、オブジェクト指向と同様、単なる設計理論の1つであり、設計思想の追求の仕方、設計の突き詰め方のヒントを与えてくれる程度のものである。
[6]より:
Patterns are architectural heuristics. Understanding them should widen your solution spectrum, not narrow it. They provide you with proven ways of solving a specific problem in programming. The reality is that you will rarely encounter that specific problem in the wild, but you will encounter variants of that problem
デザインパターンを理解すると問題解決能力が上がるべきであり、逆にそれに従うことによって問題解決手段の選択肢を狭めるものであるべきでない、という意味だと思う。
筆者は、デザインパターンは将棋の定跡のようなものだと思う。実戦において、定跡と全く同じ局面になることは滅多に無いので、ただ手順を覚えるだけではあまり役に立たないが、似たような局面になることはよくあり、定跡手順の意味を理解していると、大きなヒントになる。
同じ手でも、定跡を知らずに指すのと、定跡手順を知った上で外すのとでは、試行錯誤の質が大きく異なり、その後の勝率に差が出る。定跡を知らなくても、終盤で逆転するとか、力づくで勝ち続けることは可能だが、限界がある。終盤は法則化、体系化できないので、勝率を上げるには終盤力、つまり計算速度を上げることしか無くなる。
同様に、ソフトウェア設計も、コーディング能力に頼るのでは限界がある。それは個人の資質にも依存する職人芸であり、何よりも、習得方法、指導方法の確立が難しいので、伝達及び維持が困難である。この業界は、技術は盗むもの、とか言っていて間に合う世界ではない。だからこそ、アルゴリズムや設計理論やデザインパターンを知ることに価値があるのである。
[6]のコメント欄より:
I only like to talk about MVC now when there is something resembling Smalltalk MVC triads at work and controllers are required to move messages between triads. Otherwise I think the GOF book got it right to not include MVC as a pattern.When people say they are using MVC I take that to mean they see their application as being organized somehow into three parts that can be worked on separately:
1. data and business logic,
I don't really think MVC means much more than that anymore. Consequently its value in discussing real-world designs has become suspect.
2. presentations of that data, and
3. some sort of event management and propagation system.
[3]のコメント欄より:
One of my main issues with the whole framework/mvc debate is that it has been my experience that one size can not fit all.
どんな規模の開発にも有効なフレームワークやデザインパターンは存在しない、と言い換えても良いと思う。
[3]のコメント欄より:
The most important part of an abstraction is not what patterns it strictly adheres to, but what it provides the programmer in terms of power, maintainability and ease of use.... and back to the discussion on MVC: my 'tool' abstraction encapsulates user input processing, drawing transparent scratch information (for example to display a selection rectangle) and model object manipulation. Is the tool a controller or a view? Could it even be a model (at the application level as opposed to the document level)? The answer: who cares. These labels we use are for architectural communication and education, not as rules that must be adhered to regardless of the problem domain.
A more important question than "do your developers implement design patterns?" is "do your developers *understand* design patterns and spend the time creating, analysing and discussing abstractions that may enhance the design of your application?"
問題の抽象化の目的は、作り易さ、メンテナンス性、扱い易さなどの実際の成果であり、デザインパターンに厳密に従うことではない、と書かれている。
また、デザインパターンを使っているかどうかでなく、デザインパターンを理解して使っているかどうかが大事な問題だ、とも書かれている。
参考文献
[1] MVC As Anti-Pattern
MVCパターンは、リッチなクライアントを持つWebシステムには適さない、という主旨で、よくまとめられている。MVCパターンの限界を考える出発点として最適だと思う。
[2] A Better Understanding Of MVC (Model-View-Controller) Thanks To Steven Neiland
MVCにきちんと従うためのわかりやすい指針というか、格言のようなものが考え出されている。
[3] MVC considered harmful
本文には大したことが書かれていないが、コメント欄の議論は非常に深く、参考になる。
[4] Best Practice Software Engineering - Model View Controller
簡単なMVCの紹介。1ヶ所、上記の引用部分の記述が非常に鋭いと感じたので、挙げておく。
[5] GUI Architectures
その筋では有名な、Martin Fowler氏による、Webアプリケーションのフレームワークの進化の歴史が書かれている。必読。
[6] On Design Patterns and Reality
一般論が多いが、なかなか深く鋭い話で、一読に値すると思う。