実際、MVCとは何ですか?


202

真面目なプログラマーとして、MVCとは何かという質問にどのように答えますか?

私の考えでは、MVCは一種の曖昧なトピックです。そのため、視聴者が学習者である場合は、論争の対象とはならない一般的な用語で自由に説明できます。

ただし、知識豊富な聴衆、特にインタビュアーと話している場合、「それは正しくない!...」という反応のリスクを冒さないための方向性を考えるのに苦労しています。私たちは皆、実世界での経験が異なり、同じMVCの実装パターンに2回出会ったことはありません。

具体的には、厳密性、コンポーネント定義、部品の分離(どの部品がどこに適合するか)などに関して意見の相違があるようです。

それで、MVCを正しく、簡潔で、議論の余地のない方法でどのように説明すればよいですか?


4
注:ASP.NETで作業している場合、MVCには2番目の、曖昧でない意味があります。ASP.NETMVC-
ブライアン

MVCは、ここにも説明したcodespeaker.com/blogs/...
smzapp

回答:


156

MVCはソフトウェアアーキテクチャ(システムの構造)であり、ドメイン/アプリケーション/ビジネス(好きなものは何でも)ロジックを他のユーザーインターフェイスから分離します。これを行うには、アプリケーションを3つの部分(モデル、ビュー、コントローラー)に分けます。

このモデルは、アプリケーションの基本的な動作とデータを管理します。情報の要求に応答し、情報の状態を変更する指示に応答し、情報が変更されたときにイベント駆動型システムのオブザーバーに通知することもできます。これは、データベース、または任意の数のデータ構造またはストレージシステムです。要するに、それはアプリケーションのデータとデータ管理です。

ビューは、アプリケーションのユーザーインターフェイス要素を効果的に提供します。モデルのデータを、ユーザーインターフェイスに適したフォームにレンダリングします。

コントローラーはユーザー入力を受け取り、モデルオブジェクトとビューを呼び出して適切なアクションを実行します。

全体として、これら3つのコンポーネントは連携して、MVCの3つの基本コンポーネントを作成します。


7
+1私は、MVCをデザインパターンよりも3つ(またはそれ以上)のパターンのアーキテクチャと考えることを本当に好みます。正規の実装はありません。単に小さくはありません。すべての実装には、暗黙のコアコンポーネントよりもかなり多くのコンポーネントがあります。
ヤンニス

51
この回答には21の賛成票がありますが、「これは、データベース、または任意の数のデータ構造またはストレージシステムである可能性があります。モデルは、純粋なビジネス/ドメインロジックです。そして、これはアプリケーションのデータ管理以上のものです。ドメインロジックとアプリケーションロジックも区別します。コントローラには、ビジネス/ドメインロジックを含めたり、データベースと直接やり取りしたりしないでください。
ファルコン

9
mvcがプレゼンテーション層の外側で合理的であると主張しているというだけの理由で、私はこの答えに異議を唱えられません。答えの残りは大丈夫です。MVCはプレゼンテーション層で開始および終了する必要があり、ビジネスロジックとリポジトリを絶対に含めるべきではありません。これを行うと、アプリケーション全体がプレゼンテーション層に効果的に配置され、元のアプリ用に設計されていなくてもビジネスロジックまたは純粋なデータに直接アクセスできるAPIが使用できなくなります。これは、拡張性のために開いていない、ビューモデルは近いあなたを取得していますが、まだ疎結合を逃している
ジミー・ホッファ

6
@Jimmy:MVCの多くの構成では、モデルはUIに依存しないため、APIで再利用できます。ビューとモデルの分離がそれを処理します。しかし、それはもちろん、「モデル」を定義する方法に依存します。あなたはMVCについての判断をするつもりされている場合は、最初に説明する必要がありますされ、使用しているMVCの解釈。
オーウェンS.

5
@Yannis:これはただ疑問を投げかけます:パターンのアーキテクチャとは何ですか?なぜあなたはそれをちょうど別のデザインパターンと呼ばないのですか?GoF(およびAlexander)のデザインパターンのまさにその定義は、パターンが1つの標準的な実装を規定するべきではないことを非常に明確にします(ただし、両方の本の人気はその概念を少しアンダーカットします)。
オーウェンS.

136

類推

次のようにMVCを父に説明しました。

MVC(モデル、ビュー、コントローラー)は、保守性を改善するためにアプリケーションでコードを編成するためのパターンです。

スタジオでカメラを持った写真家を想像してください。顧客は彼に箱の写真を撮るように頼みます。

箱はモデルであり、写真家はコントローラーであり、カメラはビューです。

ボックスはカメラや写真家を知らないため、完全に独立しています。この分離により、写真家はボックスを歩き回り、カメラを任意の角度に向けて、望みのショット/ビューを得ることができます。

非MVCアーキテクチャは、密接に統合される傾向があります。ボックス、コントローラー、カメラが同じオブジェクトの場合、新しいビューを取得するたびにボックスカメラの両方を分解して再構築する必要があります。また、写真を撮るということは、常に自撮りをしようとするようなものです。


詳細な説明

MVCを理解したように感じたのは、次のメールリストの質問/回答を読んだ後です。引用:https : //mail.python.org/pipermail/python-list/2006-January/394968.html

bwahaの書き込み:

著者は、MVCデザインの例としてwxPythonのmvctree.pyを参照しています。しかし、私はまだあまりにも緑なので、その特定の例は複雑すぎて、著者が推奨している分離を理解していません。

MVCは、懸念事項の分離に関するものです。

モデルは、プログラムのデータ(プライベートデータとクライアントデータの両方)の管理を担当します。View / Controllerは、プログラムのクライアントデータと対話する手段を外部に提供する役割を果たします。

モデルは、プログラムの他の部分がモデルと対話できるようにする内部インターフェイス(API)を提供します。ビュー/コントローラーは、外部インターフェイス(GUI / CLI / Webフォーム/高レベルIPC /など)を提供し、プログラムのすべてが通信できるようにします。

モデルは、プログラムのデータの整合性を維持する責任があります。データが破損した場合、誰でもゲームオーバーになるからです。ビュー/コントローラーは、UIの整合性を維持し、すべてのテキストビューが最新の値を表示していることを確認し、現在のフォーカスに適用されないメニュー項目を無効にするなどの責任を負います。

モデルにはビュー/コントローラーコードが含まれていません。GUIウィジェットクラス、ダイアログボックスのレイアウトまたはユーザー入力を受け取るためのコードはありません。ビュー/コントローラーにはモデルコードが含まれていません。URLを検証したりSQLクエリを実行したりするコードはなく、元の状態もありません。ウィジェットが保持するデータは表示専用であり、モデルに保存されている真のデータを単に反映したものです。

さて、ここに真のMVCデザインのテストがあります。View/ Controllerが接続されていなくても、プログラムは本質的に完全に機能するはずです。OK、外の世界はその形式でそれとやり取りするのに苦労しますが、適切なModel APIの呪文を知っている限り、プログラムは通常通りデータを保持して操作します。

なぜこれが可能ですか?簡単な答えは、モデルレイヤーとビュー/コントローラーレイヤー間の結合が低いためです。ただし、これは完全な話ではありません。MVCパターン全体の鍵となるのは、それらの接続の方向です。すべての命令、ビュー/コントローラーからモデルに流れます。モデルは、View / Controllerに何をすべきかを決して伝えません。

どうして?MVCでは、ビュー/コントローラーはモデル(特に、モデルのAPI)について少し知ることはできますが、モデルはビュー/コントローラーについて何も知ることはできません。

どうして?MVCは懸念事項を明確に分離するためのものだからです。

どうして?プログラムの複雑さが制御不能になり、開発者であるあなたをその下に埋もれないようにするため。プログラムが大きいほど、そのプログラムのコンポーネントの数が多くなります。そして、それらのコンポーネント間に多くの接続が存在するほど、開発者が個々のコンポーネントを維持/拡張/交換したり、システム全体の動作を追うことさえ難しくなります。これを自問してみてください。プログラムの構造の図を見ると、木や猫のゆりかごを見るのが好きですか?MVCパターンは、循環接続を許可しないことで後者を回避します。BはAに接続できますが、AはBに接続できません。この場合、Aはモデルで、Bはビュー/コントローラーです。

ところで、あなたが鋭いなら、あなたはちょうど説明された「一方向」の制限に問題があることに気付くでしょう:モデルが許可されていないときにモデルのユーザーデータの変更をモデルがビュー/コントローラーに通知する方法View / Controllerにメッセージを送信してもかまいませんか?しかし、心配しないでください。これには解決策があります。最初は少し回り道をしているように見えても、かなりきれいです。それについてはすぐに説明します。

実際には、View / Controllerオブジェクトは、モデルのAPIを介して、1。モデルに何かを行うように指示する(コマンドを実行する)、2。モデルにそれを与えるように指示する(データを返す)ことができます。ビュー/コントローラーレイヤーは、命令をモデルレイヤーに プッシュし、モデルレイヤーから情報を取得します。

そして、最初のMyCoolListControlの例がうまくいかないのは、そのクラスのAPIに情報をプッシュ する必要があるためです。そのため、レイヤー間の双方向のカップリングに戻り、MVCルールに違反し、すぐにダンプします猫のゆりかごのアーキテクチャは、そもそも(おそらく)回避しようとしていました。

代わりに、MyCoolListControlクラスはフローを使用して、必要なときに必要なデータを下のレイヤーからプルする必要があります。リストウィジェットの場合、一般に、値の数を尋ねてから、それらの各項目を順番に尋ねることを意味します。これは、それを行うための最も単純で最もゆるい方法であり、したがって、存在する結合を最小限に抑えるためです。そして、ウィジェットが、たとえば、それらの値をアルファベット順に並べてユーザーに表示したい場合、それはその意味です。そしてその責任はもちろんです。

さて、先ほど示唆したように、最後の難問は、MVCベースのシステムでUIの表示をモデルの状態とどのように同期させるかということです。

問題は次のとおりです。多くのViewオブジェクトはステートフルです。たとえば、チェックボックスにチェックマークを付けたり、チェックを外したり、テキストフィールドに編集可能なテキストを含めることができます。ただし、MVCはすべてのユーザーデータをモデルレイヤーに保存するように指示しているため、表示目的で他のレイヤーが保持するデータ(チェックボックスの状態、テキストフィールドの現在のテキスト)は、そのプライマリモデルデータの補助コピーでなければなりません。ただし、モデルの状態が変更された場合、その状態のビューのコピーは正確でなくなるため、更新する必要があります。

しかし、どのように?MVCパターンは、モデルがその情報の新しいコピーをビューレイヤーにプッシュするのを防ぎます。ちなみに、ModelがViewにメッセージを送信して、状態が変わったことを伝えることさえできません。

よくほとんど。さて、モデルレイヤーは他のレイヤーと直接対話することは許可されていません。そのためには、それらのレイヤーについて何かを知っている必要があり、MVCルールがそれを妨げるからです。しかし、木が森に落ち、誰もそれを聞いていない場合、音がしますか?

答えは、通知システムをセットアップして、モデルレイヤーに、特に興味深いことを行ったことを誰にも告知できない場所を提供することです。他のレイヤーは、その通知システムを使用してリスナーをポストし、実際に興味のあるアナウンスをリッスンできます。モデルレイヤーは、誰がリッスンしているか(またはだれかがリッスンしている場合でも)を知る必要はありません。アナウンスを投稿し、それを忘れます。そして、もし誰かがその発表を聞いて、その後何かをしたい気がしたら-モデルに画面上の表示を更新できるように新しいデータを要求する-素晴らしい。モデルは、API定義の一部として送信する通知をリストするだけです。そして、他の誰かがその知識で何をするかは彼ら次第です。

MVCは保存され、誰もが幸せです。アプリケーションフレームワークは、組み込みの通知システムを提供する場合があります。そうでない場合は、独自のフレームワークを作成できます(「オブザーバーパターン」を参照)。

...

とにかく、それが役立つことを願っています。MVCの背後にある動機を理解すると、物事がそのように行われる理由は、一見、必要以上に複雑に見えても意味を持ち始めます。

乾杯、

持っている



86

MVCはに流行語です。

以前はパターンと見なされていましたが、1979年の元の定義は、馬鹿げたもの、受け継がれたもの、誤解されたもの、元の文脈から外れたものです。それは宗教に似たものになるまで不明確であり、これは確かにそれを守るカーゴカルティストを助けますが、その名前はもはやガイドラインの固いセットと関連付けられません。そのため、実際にはパターンと見なすことはできなくなりました。

MVCはWebアプリケーションを記述することを意図したものではありませんでした。
最新のオペレーティングシステムも言語もありません。
(そのうちのいくつかは実際に1979年の定義を冗長にしました)

作られました。そして、うまくいきませんでした。

私たちは今、わいせつなweb-mvcハイブリッドを扱っています。その流行語はひどい流行語であり、定義が不明確であり、ターゲット層としてセミリテラシープログラマーがいるため、ソフトウェアパターン全般に対して非常に悪い宣伝をしています。

したがって、MVCは、あまり考えたくない人々のために、懸念の分離になりました。

  • データモデルは、一方向に処理されます
  • 別のビュー
  • 残りは「コントローラー」という名前で、読者の裁量に任されています。

90年代のWebサイト/ Webアプリケーションは、関心の分離を適用するために実際には使用しませんでした。

それらは混合スパゲッティコードの恐ろしい欠陥でした。
UIの変更、再設計、およびデータの再配置は、信じられないほど難しく、高価で、長く、憂鬱で、不運でした。

ASP、JSP、PHPなどのWebテクノロジーにより、ビューの問題とデータ、およびアプリケーションの問題を簡単に混在させることができます。この分野の新参者は通常、昔のように複雑なコードマッドボールを放出します。

したがって、サポートフォーラムの無限ループで「MVCを使用」を繰り返し始める人が増えています。人々の数は、マネージャーやマーケティング担当者を含むように拡大しました(GUIプログラミングの時代からパターンが理にかなっている用語はすでによく知られていました)。 。

現状では、それは常識であり、方法論はありません。
これは出発点であり、解決策ではありません。癌を治すのではなく空気
吸ったり、クランチするように人々に言うようなものです。


22
確かに大部分が流行語ではありません。MVCは他のデザインパターンよりも広範かつ明確でない傾向があるため、代わりに組織化の原則またはパラダイムと考えることができます。しかし、あなたがそれを何と呼んでも、それは多くの非常に成功したオブジェクト指向フレームワークの基本概念です。それが単なる流行語、つまりあまり意味のないファッショナブルなフレーズであるふりをすることは、OPを傷つけることです。
カレブ

23
It's a fancy word for pre-existing concepts that didn't really need one.そして、どのデザインパターン/アーキテクチャがその説明に適合しませんか?
ヤニス

8
+1率直に言って、これらのほとんどは、基礎(結束、結合、読みやすさ、正統性など)を把握し、それを現代言語の機能と組み合わせれば明らかです。
ロリアン

12
The data model is handled one way, the view in another, the rest is just named "controller"+1
c69

33
-1。ばかげた+1コメントのすべてに対して-10ができたらいいのに。カップリングと凝集の基本原則を考えると、この「明白な」ものはどれですか?MVC、MVP、MVVM、Forms、Smalltalkのモデルなど、UIアーキテクチャが豊富です。一部の企業は、WS-CAFなどのように、複合アプリケーションアーキテクチャを極端にプッシュしています。「常識」があなたを自動的にMVCに導くと言うことは、デカルトのいわゆる神の証明と同じくらいの水を保持しています。それは明らかにあなたが知っていることですが、あなたの答えは、他の方法の無知か、あなた自身の視野を広げることができないことを示しています。
アーロンノート

39

それを定義する最良の方法は、それを発明したTrygve Reenskaugのオリジナルの著作物に行くことです:http : //heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html

特に、このペーパーは一般に定義テキストと見なされます:http : //heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdf

モデル

モデルは知識を表します。モデルは単一のオブジェクト(むしろ面白くない)かもしれませんし、オブジェクトの構造かもしれません...

一方でモデルとそのパーツの間には1対1の対応があり、他方ではモデルの所有者が認識しているように表現された世界があるはずです。したがって、モデルのノードは、問題の識別可能な部分を表す必要があります。

モデルのノードはすべて同じ問題レベルにある必要があり、問題指向のノード(カレンダーの予定など)と実装の詳細(段落など)を混在させるのは混乱し、悪いと考えられます。

ビュー

ビューは、そのモデルの(視覚的な)表現です。通常、モデルの特定の属性を強調表示し、他の属性を抑制します。したがって、プレゼンテーションフィルターとして機能します

ビューはそのモデル(またはモデルパーツ)にアタッチされ、質問をすることでモデルからプレゼンテーションに必要なデータを取得します。適切なメッセージを送信してモデルを更新することもあります。これらの質問とメッセージはすべて、モデルの用語に含まれている必要があるため、ビューは、モデルが表すモデルの属性のセマンティクスを知る必要があります。(たとえば、モデルの識別子を要求し、Textのインスタンスを予期する場合がありますが、モデルがTextクラスであると想定しない場合があります。)

コントローラー

コントローラは、ユーザーとシステムの間のリンクです。画面上の適切な場所に自分自身を表示するために関連するビューを配置することにより、ユーザーに入力を提供します。ユーザーにメニューやコマンドやデータを提供する他の手段を提示することにより、ユーザー出力の手段を提供します。コントローラーはそのようなユーザー出力を受け取り、適切なメッセージに変換して、これらのメッセージを1つ以上のビューに渡します。

コントローラーは、ビューを補足することはできません。たとえば、ノードのビュー間で矢印を描画して接続することはできません。

逆に、ビューは、マウス操作やキーストロークなどのユーザー入力を認識してはなりません。ユーザーコマンドのシーケンスを正確に再現するビューにメッセージを送信するメソッドをコントローラーに記述することは常に可能でなければなりません。

編集者

コントローラーは、そのすべてのビューに接続されており、コントローラーのパーツと呼ばれます。一部のビューには、ビューによって表示される情報をユーザーが変更できる特別なコントローラー、エディターがあります。このようなエディターは、コントローラーとそのビューの間のパスに接合され、コントローラーの拡張機能として機能します。編集プロセスが完了すると、エディターはパスから削除され、破棄されます。

エディターは、接続されたビューのメタファーを介してユーザーと通信するため、エディターはビューと密接に関連付けられていることに注意してください。コントローラーは、ビューを要求することでエディターを保持します。他に適切なソースはありません。


11

MVCは、プレゼンテーションからビジネスロジックを分離するために使用されるデザインパターンです。

通常は簡潔に実装されていないが、フレームワークのベースであるという事実により、他の多くの設計パターンとは異なります。

ストラテジーパターンを実装するアプリケーションは、その詳細についてほんの少しですが、WebアプリがMVCデザインパターンを使用していると言うことは、そのアーキテクチャを非常に定義しています。


2
MVC、MP、MVVMとは異なるMVCパターンを実装するための非常に特定の要件がありますが、これは厳密には役立ちません。また、他のプレゼンテーションパターンとは異なる対象ユーザーもいます。
イアン

8

MVCは、システムまたはサブシステムの次のコンポーネントを分離するソフトウェア設計です。

  1. モデル-アプリケーションまたはそのコンポーネントの状態に関するデータ。変更またはアクセスのためのルーチンを含めることができます。
  2. ビュー-データの解釈(モデル)。これは視覚的表現に限定されますが、音声、派生情報(たとえば、別のモデルオブジェクトにパイプされる統計)などです。さらに、単一のモデルに複数のビューがある場合があります。
  3. 制御-モデルの変更を呼び出すシステムへの外部入力を処理します。コントロール/ビューは密接に関連している場合があります(UIの場合)。ただし、ビューから完全に独立した他の外部入力(ネットワークコマンドなど)を処理できます。

6

MVCは概念または類似のパターンのファミリーだと思います。

この記事は読む価値があると思います。Martin FowlerによるGUIアーキテクチャ


5
そのFowlerの記事は素晴らしいものであり、MVCという用語を使用する人は誰でも読んでください。特に興味深いと思う2つのポイントは、GUIでのMVCという用語の元の使用はWebフレームワークでの使用とはかなり異なり、GUIではビューとコントローラーの分離は予想よりも役に立たないことがわかったということです。
トムアンダーソン

3

最初に、質問の質問者が誰で、どのような回答を求めているのかを判断する必要があります。この質問には、「どのような意味で?」などの別の質問で回答します。

一般にMVCを参照しているか、MVCの特定の実装(asp.net MVC、spring MVC、smalltalk MVCなど)か、技術的に何であるか、哲学的に何であるか(はい、哲学も)など。

これがテストに関する質問であり、質問者に明確にするように依頼できない場合は、コンテキストに基づいて推測する必要があります。

良い、簡単な答えは:

MVCは、より保守しやすいソフトウェアを容易にするために、構造的および動作上の問題を分離するために使用されるソフトウェアユーザーインターフェイスアーキテクチャです。

また言うことができます:

ビューをモデルからコントローラーから分離することにより、コンポーネントの責任に基づいたコンポーネントの分離を促進します。理論的には、通常は実際には、これにより、システムのさまざまな部分が混ざり合って、より複雑なシステムを作成するのを防ぐことにより、保守性が向上します。

しかし、最終的に、あなたは彼らが期待している答えを与えるかどうかで判断されます。問題に対する唯一の解決策は、彼らが期待している答えの種類を見つけることです。


2

私はそれについて私が言うことです。モバイルアプリケーションの観点から説明しようと思います。なぜなら、それは私が最もよく知っていることであり、モバイルアプリケーションを始める前に完全に理解していないと思うからです。
Androidを例にとってみましょう。
プレゼンテーション層、すなわち ユーザーインターフェイスは、XMLで完全に指定することができます(ほとんどの場合、指定する必要があります)。簡単にするために、1つのxmlファイルがアプリケーションの1つの画面を記述しているとしましょう。XMLファイルは、コントロール、コントロールのレイアウト、位置、色、サイズ、文字列ラベルなど、プレゼンテーションに関するすべてを指定します。しかし、いつ呼び出されるか、いつ画面に配置されるかについては何も知りません。スタンドアロンのレイアウトですか、それともより大きなレイアウトの一部ですか?完璧なVIEWがあります。

さて、ある時点で画面上にビューを配置する必要があるのは明らかです。あなたCONTROLLER Androidの中には、アクティビティと呼ばれます。名前が示すように、アクティビティは何らかのアクティビティを実行します。その唯一の目的が手順1で定義されたビューを表示することであっても、何らかのアクションを実行します。そのため、アクティビティはビューを取得して画面に表示します。ビューはアクティビティについて何も知らないので、同様にアクティビティは実際のプレゼンテーションについて何も知りません。私たち(プログラマ)は、アクティビティのコードを1行も変更せずに、ビューのレイアウトを複数回再配置できました。

さて、実際に何かをすることなく、あなたの素敵で、きちんと定義されたxmlレイアウトを提示することにはあまり役に立ちません。ユーザーが入力したデータを保存するとします。アクティビティは、ユーザーからのデータの取得から他の誰かへのデータの受け渡し(処理、保存、削除)まで、このプロセスに取り組む必要があります。誰に渡されますか?さて、モデルへ。私はモデルを純粋なものと考えるのが好きです。住んでいるアプリケーションコンテキストについて何も知らないjavaクラス(実際にはほとんどありません)。

名前、住所、年齢という3つのプロパティを持つクラスPersonがあるとします。XML定義のレイアウトには、ユーザー入力用の3つのフィールド(名前、住所、年齢)があります。私のアクティビティは、ユーザー入力から3つの値を取得し、新しいPersonオブジェクトを作成し、Person固有のロジックの処理方法を知っているメソッドを呼び出します。そこにあります。モデルビューコントローラー。


1

私はいつも、パターンは新しいものではなく、長年にわたって存在していることを伝えることから始めます...この時点で、彼らは私に好奇心look盛な外観とBAMを与えます!

それから、以前の回答のようなさまざまなポイントについてお話したいと思いますが、JB Kingが言ったように、ASP.NET MVCなど、文脈的にも重要であると思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.