組み込み機器向けandroidに関してのつぶやき
「RESTful MVC」なアーキテクチャの話

デザイン・パターンとは何か

 先日のMVCの議論の際には、私自身いろいろと勉強させていただいたが、少し心配になったのは、「MVCの定義だって時代とともに変わる」「ウェブサービス用のMVCはSmalltalk時代のMVCとは異なるもの」「MVCなんか理解してなくてもアプリケーションが作れればいいじゃん」など、そもそも「MVCとは何か」どころか「デザイン・パターンとは何か」を理解していないんじゃないかと思われる発言が見られたこと。ということで、今日はデザイン・パターンについてひと言。

 デザイン・パターンとは、(業界に蓄積されたノウハウに立脚した)何かを作る際の指針のこと。ソフトウェアに限らず、ものを作るときにはさまざまな(場合によってはお互いに矛盾する)要求条件や制約が課せられるわけだが、そんな時に過去にさまざまな事例を解決してきた先人の知恵を「パターン化」してノウハウとして身につけておけば、似たような事例に出会った時に効率よく正しい答えにたどり着ける、というのがデザイン・パターン活用の背景にある考え方である。

 なので、MVCのようにいったん明確に定義されたデザイン・パターンは「時代とともに変わったり」は決してしないものである。もちろん、時代とともに要求条件や制約も変化するので、過去のデザイン・パターンのどれもがしっくりと来ない事例に出会う可能性も十分あり、その場合には自分なりの独自の設計をしなければならない。そんなことを多くの人が繰り返しているうちにある特定の形のデザインがたくさんの人の支持を得て新しいデザイン・パターンとして認知されることもあるが、それはあくまで「新しいデザイン・パターンが作られた」だけの話であり、「過去に定義されたデザイン・パターンそのものが変化した」のではない。

 ここを理解していただければ、「MVCの定義だって時代とともに変わる」「ウェブサービス用のMVCはSmalltalk時代のMVCとは異なるもの」などの発言がいかに的外れなものかが分かっていただけると思う。

 MVCがデザイン・パターンであることを皆が理解していれば、「ModelとView/Controller間のインターフェイスをきちんと設計しなければならないMVCは、アジャイルな開発には向かない」「いや、たとえアジャイルでもそこをさぼると後々のコストが高くなる」とか「RailsでModel層と呼ばれているActiveRecordは、データベースのテーブルとModelが1対1という比較的シンプルなアプリケーションの場合には文字通りModel層の役目を果たすことができるが、ビジネス上のモデルを複数テーブルにまたがって実装する必要がある場合は本来Model層にあるべきロジックをController側に記述せざるをえないので、その場合にはMdel/View/CcontrollerというよりはData/View/Model+Controller の形になる」などの建設的な議論が可能になる。

【追記】

 ちなみに、混乱の元はMVC2なる言葉。Sun MicrosystemsがMVCをウェブサービスに適用したアーキテクチャを提案した際に、JSPがViewとControllerの両方の役目を果たすものを Model1、ちゃんとMVCを適用してBeans(Model)+JSP(View)+Servlet(Controller)の形にしたものを Model 2(もしくは MVC Model 2)と呼んだことに始まる(参照)。この "MVC Model 2" を "MVC2" と省略して呼んだ人がいたために、「ウェブサービス用のMVCはSmalltalk時代のMVCとは異なるもの」などという混乱をまねいているのだ(参照)。

Comments

MY

まあ言葉って使う人によって変わってくるといいますからね。
昔、言われてた意味と現代では違うっていうのもザラにありますからねぇ。
話をしていて、「?」って思うことは多々ありますよ。

BeansってModelだったんですか?
てっきり、Data(ValueObject?)だと思ってました。
あとDataってViewへ渡すオブジェクトの事ですか?
Daoなどで使うテーブルなどのデータ構造ってEntityとかって言いません?
(EJBのころの名残りですかね?)
まあ、あまりこの辺の名称とか関係なしに実装するタチなので、気にしてませんでした。

まあControllerにロジック書いちゃう人ってスクリプト言語系の人に多いと思うんだけど、これって偏見?

正直PHP知ったとき、「JSP上でロジック書いちゃってるようなものジャン、へぇ~そういう発想もあるのねぇ」って思いました。
人間、目の前の面倒なことは早く済ませたいと思うから、そうしてるんだと思いました。
これも「アジャイル」って奴ですかね;P

satoshis

MVCはデザインパターンというより、アーキテクチャパターンですよね。まあ、デザインパターン⊃アーキテクチャパターンとも言えるので、間違いではないと思いますが。
自分も、MVCについてちょっとだけですが、ブログに書いてみました。
https://d.hatena.ne.jp/satoshis/20091013/p1

Makoto

こんにちは。いつも興味深く拝見しております。

デザインパターンに関してですが、定義自体は変わらないかもしれませんが、実装の仕方は言語によってかなり変わってくるということはあります。例えばC++ やJavaではいくつものサブクラスを使って実装していたデザインパターンの多くが、Rubyではブロックを使って簡単に実装できたりします(またJavascriptにはInheritance自体が言語として存在しないので、C++を前提としたGoFのデザインパターンの実装例をそのまま適応しようとすると、逆にコードが肥大化したりする可能性があります)。またイタレーターなどはRubyでは言語が実装しているので、ユーザーはそれをわざわざデザインパターンとして認識、自分で実装する必要もあまりありません。人気の言語というのは時代によって変遷していくので、そのため「各デザインパターンの重要性は時代によって移り変わる」ということはあり得ると思います。

y

satoshiさんが書かれているのはパターンの原理・原則についての話ではないかと思います。たしかに、パターンのエッセンスは時代が移ってもそうそう変わるものではないと思います。
他の方々が書かれている時代とともに変わるというのは、パターンの実装や詳細についての話であって、MやV、それにCの詳細な定義は変化するということだと理解しました。
抽象レベルでは M、V、Cをきれいに分離できるが、実装レベルではMとV、VとCの境界は揺らぎ変化し続けているということではないかと。

emeitch

MVCの議論、楽しく拝見させていただいております。
今回、少し思う所があったのでコメントさせて下さい。

> なので、MVCのようにいったん明確に定義されたデザイン・パターンは「時代とともに変わったり」は決してしないものである。

私も一度明確に定義されたMVCの中身は変わってほしくないと思っております。

> 「ウェブサービス用のMVCはSmalltalk時代のMVCとは異なるもの」などの発言がいかに的外れなものかが分かっていただけると思う。

しかしながら、Rails等いわゆるWebフレームワークのMVCと、Smalltalk由来のMVCの中身は異なると言わざるを得えません。

中島さんも本エントリーの主題とされた、各種ソフトウェアアーキテクチャ・パターンを記述した書籍「ソフトウェア アーキテクチャ ソフトウェア開発のためのパターン体系(Pattern-Oriented Software Architecture)」に記載された「Model-View-Controller」から、その根拠となる部分を抜粋します。

本書では、モデルの持つ特性として「更新伝播メカニズム」を挙げています。Observerパターンや、Publisher-Subscriberパターン等で実装されるモデル状態の変更通知メカニズムのことです。これにより、ビューとモデルの依存関係をより簡単に管理することができるようになります。

この特性はGUIを主体としているSmalltalk由来のMVCの中でも非常に重要な部分になります。事実、中島さんが挙げられている文献のを見ていただいても、この通知メカニズムに関しての記述があります。

https://itpro.nikkeibp.co.jp/article/COLUMN/20080610/307218/?ST=oss
https://en.wikipedia.org/wiki/Model-view-controller

しかしながら、いわゆるWebフレームワークのMVCでは、このような「更新伝播メカニズム」を含んでいません。

また「コントローラ」の持つ役割にも大きな差異が見られます。

本書ではコントローラはユーザ入力などのイベントを受け取り、そのイベントをモデルやビューへのリクエストに変換するのがその役割となっています。これは、Smalltalk由来のMVCにおけるコントローラの役割とも一致しています。ビューとモデルの中間に位置するコンポーネントなどでも決してありません。

しかし、いわゆるWebフレームワークのMVCでは、コントローラの制御は多岐にわたっており、本書のような単純な役割におさまっていません。

上記2点のみでも、十分にWebフレームワークのMVCと、Smalltalk由来のMVCは異なると私は考えます。

見る方によっては、細かいポイントを突いているだけに見えるかもしれません。しかし、これらのことはSmalltalk由来のMVCを大切に思う私にとって瑣末ですむ問題と思っておりません。また、中島さんと考えを同じく、基本原理の定義を変えてしまうことはとても混乱を招くのでやめたほうが良いと思っている、故に無視できません。

Satoshi Nakajima

>Rails等いわゆるWebフレームワークのMVCと、Smalltalk由来のMVCの中身は異なると言わざるを得えません。

感じていらっしゃることはもっともだと思います。「MVCの中身は異なる」と言ってしまうからあたかもMVCそのものが変化したように感じてしまう人が多いんですね。そう言わずに、「MVCというデザインパターンを当てはめた"結果"が異なる」と言えば誤解が生じにくいと思います。デザインパターンはあくまでデザインする上での指針でしかないので、「ウェブサービスにMVCを適用した場合には、Modelの変化Viewに伝えるを更新伝播メカニズムは不要」という話です。

hiro

デザイン・パターンに思うこと。

OOPを勉強し始めの頃のエンジニアによくある傾向に思うのですが、やたらGoFのデザイン・パターンをまず最初に勉強してしまい、アプリケーション・アーキテクチャのパターンは余り注力しないケースが多い。
エンタープライズ・アプリケーションの構築にはGoFのようなPrimitiveなパターンより、PofEAAなどのパターンの方が有益です。(J2EEパターンはそもそもいまいちだし、カビ臭い感じがするので参考程度に)
さらにひどいのは、そのために周りの人の使う用語を勝手に正しいと思いこみ、誤った用語がどんどん浸透していることです。

Value Object、DTO、Facadeなど、皆さんの現場は正しく使っていますか?

emeitch

> デザインパターンはあくまでデザインする上での指針でしかないので、「ウェブサービスにMVCを適用した場合には、Modelの変化Viewに伝えるを更新伝播メカニズムは不要」という話です。

少なくとも、先に挙げた書籍「ソフトウェア アーキテクチャ」、通称POSA本では、更新伝播メカニズム抜きにMVCを語りえぬ内容となっています。これはMVCを説明するSmalltalk関連の書籍でも同様のことが言えます。そのくらい更新伝播メカニズムはMVCを語る上で重要な"理念"であると考えています。

また、コントローラの入力イベントを受けるという役割を、大きく変質させてまで、Webのアーキテクチャに合わせる必要があるのでしょうか?

この更新伝播メカニズムの無視や、コントローラの役割を変質させるような態度が、「基本原理の定義を変えてしまうこと」に当てはまるように思えてしかたありません。

もちろん、MVCの明確な定義などどうでもよい、と思う方とこのような議論をしても仕方ありません。MVCの明確な定義を大事にしている中島さんであるからこそ意味ある議論だと思っています。

ちなみに、中島さんの言う「明確に定義されたMVC」というのはどこに記述されているMVCでしょうか?

私は、今回この定義としてPOSA本を挙げさせてもらいました。アーキテクチャパターンを記述した書籍としては代表的ですし、MVCに関しても適切な解説がなされていると感じたからです。

私が感じるに、中島さんの語られているMVCは、ファウラーの言う「プレゼンテーションとドメインの分離」に見えてしかたありません。

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

もちろん、MVCはこの「プレゼンテーションとドメインの分離」によるメリットを享受できる構造を持ってはいますが、それだけが本質ではありません。

uehaj

こんにちは。この論争を見ていて思い出されるのは、
12年前の(!)fj.comp.oopsの「Factory論争」などです。

高木さん自身がまとめ資料を公開されています。

https://java-house.jp/~takagi/paper/oo2001-panel-pattern-takagi.pdf

趣旨が近いのではないかと思います。ただ、「MVC」自身はGOFパターンではないし「明確な」デザインパターン言語としての定義も無いと思うので今回の件はグレーゾーンと思います(個人的には、MVCの本質はモデルからビューへの依存性の排除、そのための制御逆転、手段としてオブザーバパターンであることだと思ってるので、整合性保証とかロジックの置き場所とかはMVCの本質とは関係なく今回の議論は「最初から」かなりずれまくってると思います)。

MVC2の2を略したて使うことが混乱の元凶の一つだということはその通りです。

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been posted. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Your Information

(Name is required. Email address will not be displayed with the comment.)