web-dev-qa-db-ja.com

MVCでは、複数のビューが同じコントローラーを持っているか、1つのビューが1つの固有のコントローラーを持っている必要がありますか?

MVCを中心としたプロジェクトのアーキテクチャを設計しているときに、いくつか質問があります。 (これはC++/Marmalade SDKプロジェクトです。特定のMVCフレームワークを使用していません。作成しています。)

いくつかの記事( 元のSteve Burbekの記事 など)で、私はこの概念を文字通り取り上げたので、「MVCトライアド」という概念を読み続けています。初めて読んだとき、アプリケーションは「MVCトライアド」ユニットを中心に構築されているように見えました-想定した各UIピースに対して1つですが、これはかなり柔軟性がなく、MVCの使用方法ではないように思います。次に、この問題をさらに調査したところ、コントローラーとビューの密結合、つまり1対1の関係の例がいくつか見つかりました。TextEditViewにはTextEditControllerがあります。

しかし、プロジェクトに戻ると、1つのコントローラー(AddElementControllerのような「論理ユニット」による)と、その特定のコントローラーの複数のビューがあると便利な場合があります。

AddElementControllerのような、何らかのタブUIが必要なことを明確に考えています。タブにAddElementTabViewといくつかのAddImageView、AddSoundViewなどがあるAddElementControllerが必要ですか?または、各タブビューに異なる「サブコントローラー」を用意する必要がありますか?

要約すると、MVCパターン(このパターンのXフレームワークの特定の理解/実装ではない)に関して、コントローラーに複数のビューがあるのは正しいですか、それとも各ビューに特定のコントローラーがあるべきですか?

また、コントローラーにいくつかの状態情報を保持することは正しいですか、それともステートレス(状態がドメイン以外の状態モデルに配置される必要があることを意味する)である必要がありますか?

よろしくお願いします。

15
pedrosanta

問題は、MVCパターンが実際には存在しないシステムで設計されたことです。 UIライブラリが存在しなかった時代にSmalltalkで発明されました。ウィンドウダイアログを作成するには、すべてのボックスを描画し、適切な四角を強調表示し、描画しているテキストが正しい場所に配置されていることを確認します...など...

大きなキャンバスを1つだけ使用してダイアログアプリを作成するとしたらどうでしょうか。それがMVCが生まれる世界です。

このシステムの「ビュー」はテキストボックスであり、ボックス、テキスト、選択した領域の描画、テキストの変更への応答などを担当するクラスでした。

「コントローラー」は、このボックス内で発生したマウスイベント(マウスの移動、キーダウン、キーアップ、クリックなど)をとる別のクラスで、何が起こったかを決定します。テキストを変更する必要がありますか?選択を変更する必要がありますか?そのようなもの。

「モデル」は、コンポーネントの基本的なデータと状態を表すもう1つのクラスです。テキストボックスモデルには、もちろん、テキスト、フォント、選択などが含まれます。

ご覧のとおり、このような状況では、3つのコンポーネントが1つのアイデアの表現に非常に絡み合っています。この文脈では、「トライアド」について話すことは理にかなっています。

今日、UIライブラリの作成に取り組んでいて、生の描画コマンドを使用している場合は、同様のことを行うでしょう。しかし、「MVC」パターンの適用は、当初の目的を超えて広がっています。今日では、実際には完全なダイアログである「ビュー」と、「textChanged」や「buttonClicked」などのイベントに応答するコントローラーがあります。今日のMVCのモデルは通常、システムからかなり切り離されたものです(ただし、通常、ある種のオブザーバーインターフェイスを提供することによってビューにリンクされています)。1つのモデルに関連付けられた多くのビューがある場合があります。

たとえば、私が最近設計したシステムでは、単一のドキュメント「ホルダー」とそのアクティブなドキュメントをすべて観察する約10以上のビューがありました。メインの描画インターフェイスは、ドキュメントのレイアウト、選択したアイテムを監視してレコードインターフェイスを提供するさまざまなプロパティビュー、および表示されているウィンドウだけではなくドキュメント全体を表示するメインビューの縮尺表現と相互作用しました。これらのビューの一部には、GUIイベントをドキュメントへの変更に変えるさまざまな複雑さのコントローラーがあり、それが今度はさまざまなビューに通知します。

このような関係を「トライアド」と呼ぶことはできますか?おそらく、しかし、それはMVCの以前の古いアプリケーションの多くを暗示していると思います。

コントローラを異なるビューで共有できますか?ビューの類似度によって異なります。一般に、このタイプのオブジェクトは、それが制御しているビューに固有の動作を持ち、操作しているモデルが非常に再利用可能であることがわかりましたが、常に例外があります。

14
Edward Strange

場合によります。 MVCにはいくつかのバリアントがあり、1対1の関係のみが意味を持つもの(「控えめなダイアログボックス」など)とそうでないものがあります。最も重要なMVCバリアントを説明する「 Build Your Own CAB 」シリーズの記事を読むことをお勧めします。

5
Doc Brown

ビューのMVCにはコントローラーがありません。コントローラーはボスなので、コントローラーはレンダリングするビューを決定し、ビューはどのコントローラーがビューを要求したかを気にしません。

コントローラーから複数のビューを持つことができます。 MVCパターンを使いたい場合は、ビューごとにモデルを作成することを検討してください。

3
Mert Akcakaya

コントローラのポイントは、ドメインモデルとのユーザーの対話を制御することです。つまり、ユーザーが見るもの(ビュー)とアプリケーションの状態(モデル)の間の間接的なレベルです。

ユーザーが要求を行うと、それはコントローラーに送られます。コントローラーは、通常、ある種のサービスクラスを通じて、その要求をアプリケーションに中継する方法を決定します。次に、そのサービスクラスからの応答を解釈し、ユーザーに送り返すビューを決定します。

ユーザーがコントローラーに対して行うことができる要求の種類が1つだけであり、常に同じ種類の応答が必要な場合、コントローラーは常に同じビュー(1:1)を返すことがあります。たとえば、HelloWorldControllerは常に「Hello、World!」を表示するHelloWorldViewを返します。

一方、コントローラーは、モデルが伝える内容に応じて、さまざまなビューを決定する必要があります。 TeamRosterControllerは、要求されたチームのタイプに応じて、RugbyTeamRosterViewまたはFootbalTeamRosterViewを返す場合があります。

コントローラーはステートレスであることが一般に望ましいですが、ユーザーセッションの状態へのアクセスが必要または望ましい場合があります。可能であれば、その状態へのアクセスを個別に管理する必要があります。

実際のMVCフレームワークを見て、その機能と動作を確認することを強くお勧めします。使用する必要はありませんが、自分で作成する前に理解を深めることができます。

3
Matthew Flynn