web-dev-qa-db-ja.com

MVCの「C」は本当に必要ですか?

Model-View-Controllerパターンにおけるモデルとビューの役割は理解していますが、コントローラーが必要な理由を理解するのに苦労しています。

MVCアプローチを使用してチェスプログラムを作成しているとしましょう。ゲームの状態はモデルでなければならず、GUIはビューでなければなりません。この場合、コントローラーは正確には何ですか?

タイルをクリックしたときに呼び出されるすべての関数を備えた別のクラスですか?ビュー自体でモデルのすべてのロジックを実行しないのはなぜですか?

39
Anne Nonimus

あなたの例を使用すると、コントローラーは合法的な動きかどうかを決定するものになります。コントローラは、モデルから受け取った情報を使用して、起動時にボード上の部品を配置する方法をビューに通知します。コントローラーで処理できるものは他にもありますが、重要なのは、そのレイヤーでビジネスロジックについて考えることです。

コントローラーが行うのは、サインアップページのように情報をやり取りすることだけです。また、ルールを適用したり、複雑な計算をしたりするなど、その層で実行する必要がある多くのことがあるので、コントローラーは開発の難しい部分です。コントローラを忘れないでください!

4
JustinDoesWork

ビュー自体でモデルのすべてのロジックを実行しないのはなぜですか?

コントローラは、モデルとビューを結び付ける接着剤であり、それらを分離するための断熱材でもあります。モデルはビューについて何も認識してはならず、その逆も同様です(少なくともAppleのバージョンのMVCでは)。コントローラーは双方向アダプターのように動作し、ビューからのユーザーアクションをモデルへのメッセージに変換し、モデルからのデータでビューを構成します。

コントローラを使用してモデルとビューを分離すると、コードの再利用性、テスト性、柔軟性が向上します。チェスの例を考えてみましょう。モデルにはもちろんゲームの状態が含まれますが、動きが合法かどうかの判定やゲーム終了時の決定など、ゲームの状態の変更に影響を与えるロジックも含まれる場合があります。ビューはチェス盤と駒を表示し、駒が動くとメッセージを送信しますが、駒の背後にある意味、各駒の動きなどについては何も知りません。コントローラーはモデルとビューの両方について知っているだけでなく、プログラムの全体的な流れ。ユーザーが「新しいゲーム」ボタンを押すと、モデルにゲームを作成するように指示し、新しいゲームの状態を使用してボードを設定するコントローラーです。ユーザーが移動した場合、コントローラーはコマンドをモデルに中継し、応答に基づいて移動を許可するかどうかを決定します。

モデルとビューを別々に保つことで得られるものを見てください。

  • 他のモデルを変更することなく、モデルまたはビューを変更できます。どちらかを変更するときにコントローラーを更新する必要があるかもしれませんが、ある意味、これは利点の一部です。変更する可能性が最も高いプログラムの部分がコントローラーに集中しています。

  • モデルとビューの両方を再利用できます。たとえば、有名なゲームを説明するモデルとして、RSSフィードと同じチェス盤ビューをモデルとして使用できます。または、同じモデルを使用して、ビューをWebベースのインターフェースに置き換えることもできます。

  • モデルとビューの両方のテストを記述して、意図したとおりに機能することを確認するのは簡単です。

  • 多くの場合、モデルとビューの両方が標準部品を利用できます。それは、配列、マップ、セット、文字列、およびモデルの他のデータコンテナーです。ボタン、コントロール、テキストフィールド、画像ビュー、テーブル、その他のビュー。

39
Caleb

この一般的な設計パターンを実装する方法は数多くありますが、基本的な考え方は、必要に応じてさまざまな懸念事項を分離することです。 MVCは、次の意味で優れた抽象概念です。

Model:意味を問わず、そのデータを表します
View:意味する可能性があるものは何でも、ユーザーインターフェイスを表します
Controller:意味が何であれ、モデルとビューを相互作用させる接着剤を表します

ロット全体を指定しないため、非常に柔軟です。多くの人が多くの帯域幅を浪費し、各要素が何を意味するのか、これらの代わりにどのような名前を使用すべきか、そして本当に3または2または4または5のコンポーネントがあるべきかについて議論していますが、それはある程度。

考え方は、ロジックの異なる「チャンク」を分離して、重複しないようにすることです。プレゼンテーションの要素をまとめ、データの要素をまとめ、ロジックの要素をまとめ、コミュニケーションの要素をまとめます。などなど。ある程度、これらの懸念事項の重複が少ないほど、興味深いことを簡単に行うことができます。

あなたが本当に心配する必要があるのはそれだけです。

7
tylerl

これまでのところすべての良い答え。私の2セントは、コントローラーは主に何やどこなどの質問で構築されていると考えるのが好きだということです。

  • チェスの駒(ビュー)をxに移動できるかどうか尋ねられました。それは...ですか
    許可されますか?確かではありませんが、どこで誰に尋ねればよいかわかります(モデル)。
  • 何かが私のデータを保存するように頼みました。一体どうやってそれを行うのですか?私はどこに尋ねればよいか知っています!データをどのように保存するか、またはどこに保存するかはわかりませんが、Repositoryクラスは知っている必要があります。転送して対処させていただきます。
  • モデルが移動したユーザーに現在のチェスの駒の位置を表示する必要があります。作品を緑と黄色のどちらで表示するかわかりませんか?気にしてるバー、私はこれを処理できるビューがあることを知っているので、データを渡して、どのように表示されるかを彼らが決めることができます。

これらの小さなスニペットは、MVCが伝えようとしている抽象化と概念を思い出そうとしている例です。何を、どこで、どのようにして私の3つの主要な思考プロセスがあります。

内容と場所=>コントローラ方法と時期=>モデルとビュー

本質的に、私のコントローラーのアクションは小さくコンパクトである傾向があり、それらを読むとき、時々時間の無駄のように見える傾向があります。綿密な調査では、彼らは信号機の役割を果たしており、さまざまな要求を適切な労働者に伝えていますが、実際の作業は自分で行っていません。

4
dreza

これは、イベントハンドラーを処理するときに実際に使用されますが、ビューとモデルの間の相互作用を処理するにはコントローラーが必要です。ビューがモデルについて何も認識しないようにするのが理想的です。考えてみてください。jspがすべてのデータベース呼び出しを直接行うようにしますか? (それがログインルックアップのようなものでない限り)ビューは、データをレンダリングし、ビジネスロジック自体ではなく、ビジネスロジックを持たないようにする必要があります。

GWTでは、MVPでより明確な分離が得られます。ビューにはビジネスロジックはありません(正しく実行されている場合)。プレゼンターはコントローラーとして機能し、ビューにはモデルの知識がありません。モデルデータは単にビューに渡されます。

2
user39741

コントローラは、ビューとモデルの両方のインターフェースを抽象化するのに役立つため、お互いについて直接知る必要はありません。オブジェクトが知る必要のある情報が少ないほど、ポータブルでユニットテストが可能になります。

たとえば、モデルは1つのコントローラーを通じてそれ自体の別のインスタンスを再生している可能性があります。または、ネットワーク化されたコントローラーが2つのプレーヤーのビューオブジェクトを接続することもできます。あるいは、誰も知らないチューリングテストかもしれません。

2
hotpaw2

ドキュメントビュー(つまり、モデルビュー)は、MFCで記述された大部分のWindowsアプリの標準モデルであるため、多くの場合に機能する必要があります。

1
Martin Beckett

Model-View-Controllerパターンにおけるモデルとビューの役割は理解していますが、コントローラーが必要な理由を理解するのに苦労しています。

それでよろしいですか(少なくとも最初に説明したとおり)モデルのポイントはドメインモデルです。ビューは、ドメインモデルをユーザーに表示することになっています。コントローラは、低レベルの入力を高レベルのモデルの発話にマッピングすることになっています。私の知る限り、その理由は次のようなものです。A)SRPの高レベルの使用。 B)モデルはアプリの重要な部分と見なされていたので、重要ではなく、速く変化するものはモデルから除外してください。 C)簡単にテスト可能な(そしてスクリプト可能な)ビジネスロジック。

チェスプログラムをブラインドで使用できるようにしたい場合は、ビューを音声バージョンとキーボードで動作するコントローラーに交換してください。メールでゲームを追加する場合は、テキストを受け入れるコントローラーを追加します。ゲームのネットバージョン?ソケットからのコマンドを受け入れるコントローラーがその仕事をします。素敵な3Dレンダリングを追加します。クールな新しいビューです。必要なモデル変更がゼロチェスはまだチェスです。

入力をモデル表現と混在させると、その能力が失われます。突然チェスはチェスではありません、それはキーボードまたはネットワーク接続を備えたチェスとは異なる、マウスを備えたチェスです。

1
stonemetal

静的なWebページを表示するブラウザを考えてみてください。モデルはHTMLです。ビューは画面上の実際の結果です。

次に、JavaScriptを追加します。それがコントローラーです。ユーザーがボタンをクリックするか、イベントがJavaScriptに送信されたものをドラッグすると、何をすべきかを決定し、基になるHTML(モデル)を変更し、ブラウザー/レンダラーがそれらの変更を画面(ビュー)に表示します。

おそらく、別のボタンがクリックされ、イベントが何らかのハンドラー(コントローラー)に送信されます。それにより、さらにデータの要求がWebサービスに送信される場合があります。次に、結果がHTML(モデル)に追加されます。

コントローラはイベントに応答し、モデルの内容を制御します。したがって、画面/ビューの内容を制御します。

少し後戻りすると、ブラウザ全体をビュー、サーバーをコントローラ、データをモデルと考えることができます。ユーザーがサーバー(コントローラー)に送信したイベントをブラウザーのボタンをクリックすると、リソースがHTMLページ(モデル)として収集され、ブラウザーに返されて表示(表示)されます。

Asp、php、またはJavaであるかどうかにかかわらず、サーバーのダウン 'code'(コントローラー)はクリックイベントを受け取り、データベースまたはドキュメントリポジトリ(モデル)にクエリを実行してHTMLを作成します。サーバーからすべてのアクションの結果は、基礎となるデータストア(モデル)のビュー(HTML)ですが、クライアントから見ると、サーバーへの要求の結果はモデル(HTML)です。

HTMLでJavaScriptを乱雑にしたり、HTMLでPHP=モデル、ビュー、コントローラーを混乱させたりしても、サーバーへのリクエストとサーバーからの応答を考えても単純な双方向のストリートとしてのサーバー、モデル、ビュー、およびコントローラーがまだあります。

0
zeus

MVCは馬鹿げていると思います。おそらく特定の領域ではうまく機能しますが、個人的に私が書いたWebサイトでもmvcには適していません。あなたがフロントエンド、バックエンドを聞き、データベースエンドや何か他のエンドを決して聞いていない理由があります

IMOには、API(バックエンド)と、APIを使用するアプリ(フロントエンド)が必要です。 GETリクエストコントローラー(バックエンドAPIを呼び出すだけ)とhtmlビューを呼び出すことができると思いますが、ビューを純粋なhtmlやバックエンドAPIであるモデルとして話している人の声は通常聞こえません。

IMOはすべて、堅牢なAPIである必要があります。実際、それらは(クリーンで十分に構築されている場合のように)堅実である必要はありませんが、その内部はプライベートのままであり、APIのapp/frontend/outsideはデータベース接続を言ったり、生のクエリを実行したりすることはできません。

ここで、コード/デザインに接着剤が含まれる場合は、その問題を解決します。チェスゲームで編集してGUIのスキンを作成できるマークアップがある場合、GUIはcoords/inputを収集し、MovePiece(srcPosition、dstPostion)を呼び出します(これにより、ブール値または列挙型が返され、有効な移動かどうかがわかります)そして、すべてのロジックがモデルに含まれていることを確認してから、MVCと呼びます。ただし、私はまだクラスとAPIで物事を整理し、すべてに触れるキッチンシンククラスがないことを確認します(すべてについて知る必要のあるAPIもありません)。

0
user2528