14

ユーザーコントロールに関連するため、MVP のいくつかについて頭を悩ませようとして楽しんでいます。私は.NET WinForms(またはそれに近いもの)とSupervising Controllerパターンを使用しています(まあ、私はそうだと思います:)。

ユーザー コントロールは、それ自体が MVP アプリケーションの一部です (そのビューであり、関連付けられたプレゼンターなどがあります)。プレゼンターは常に最初に開始され、モデル、ビューの順に開始されます。ビューはその UI を構築します。その一部は、ビューである新しい UC になります。

(フォーム)PresenterはUC Presenterについて知る必要がありますが、Viewがどのように構成されているかについては何も知らないと思います。たとえば、フォーム プレゼンターは、UC がフォームの Controls コレクションの一部であることを知りません。

さらに、設計経験は変更されるべきではありません。ビュー(フォーム)のIOW開発者は、ツールボックスからユーザーコントロールを選択してフォームにドロップできるはずです。

それでは、私の質問に進みます。まず、上記の私の仮定は正しいですか?やや見当違い?めちゃめちゃ?WTFあなたは考えていますか?

第 2 に、フォーム ビューで UC ビューを呼び出し、フォーム プレゼンターで UC プレゼンターを呼び出して、UC ビューにそのプレゼンターが何であるかを伝える何らかのメカニズムを持たせることは正しいですか (十分ですか?)。これは私の「Presenter first」ルールに違反していますが、それ以外の方法がわかりません。

その他の考え、提案、コメントは喜んで受け入れます。

-- nwahmaet

4

3 に答える 3

13

プレゼンターは、プレゼンテーション層の「自律状態」と考える必要があります。これは、モデルの状態のビューのプレゼンテーションが同期していることを保証する責任があることを意味します。私がこれを持ち出す理由は、MVP の「パターン」が、物事をどのように分離すべきかという独断的な見方でしばしば失われるためです。これが、Martin Fowler が MVPパターンに関する用語を明確にしようと決めた理由の 1 つと思われます。

私の好きな MVP のフレーバーはパッシブ ビューなので、私の答えはそれに基づいています。

私は、パッシブ ビュー パターンを使用して、複合ユーザー コントロールとフォームを頻繁に実装しています。基本的に 3 つの異なる構成があります。

  1. 階層内のすべてのユーザー コントロールに対して 1 つのプレゼンター。インターフェイスを使用してビューをフラット化します。
  2. 複合ツリー内のユーザー コントロールごとに 1 つのプレゼンター。各親プレゼンターは、子プレゼンターのインスタンス化と初期化を担当します。ユーザー コントロールは設計時に作成され、プレゼンターなしで (プレゼンテーション動作なしで) 機能できます。
  3. 複合ツリー内のユーザー コントロールごとに 1 つのプレゼンター。すべてのプレゼンターは、上位レベルのコントローラー クラスを介して疎結合されています。コントローラー クラスは、プレゼンターの構築、接続、イベントの調整を担当します。

これは私にとっては最後の解決策ですが (複雑であるため)、最後の選択肢があなたが探している解決策だと思います。

于 2009-01-15T15:33:19.030 に答える
4

私が取り組んでいるアプリケーションで、この正確な問題に数か月間直面しています。私が最近得た結論は、多くの場合、パターンを「壊す」ことなく、ウィンドウレベルとユーザーコントロールレベルの両方でMVPパターンを適用することは不可能である可能性があるということです。

私の考えでは、ユーザーコントロールはビューの実装の一部であり、プレゼンターはビューの実装内で何が起こっているのかを知らないはずです。つまり、ウィンドウレベルのプレゼンターはユーザーコントロールのプレゼンターを知らないはずです。したがって、前者による後者のインスタンス化を含め、それらの間に通信があってはなりません。ユーザーコントロールのプレゼンターはウィンドウビューの実装の一部であると主張される可能性があるため、ウィンドウビューはユーザーコントロールのプレゼンターをインスタンス化する可能性があります。ただし、ビューがモデルクラスを認識していないため、プレゼンターが必要とするモデルクラスを挿入することはできません。

私が到達していると思う結論は、すべてのユーザーコントロールはビューの実装に固有であるため、より大きなパターンのビューサイロ内に完全に含まれている必要があるということです。そのため、彼らは独自のプレゼンターを持つことができません...少なくともコントロールの実装自体にバンドルされていません。代わりに、ビューインターフェイスに表示されるパススルーフィールドを介して、親ウィンドウのプレゼンターによって間接的に操作する必要があります。つまり、ユーザーコントロールは、独自のインターフェイスではなく、親ビューによって実装された共通のパススルーインターフェイスを介してプレゼンターに公開されます。これを「部分ビューインターフェイス」と呼びます。

プレゼンターには、この部分ビューインターフェイスでのみ機能する再利用可能なサブプレゼンタークラスのインスタンスと、モデルの関連部分を含めることができます。これにより、コントロールを使用する必要があるたびにモデルから変換するプレゼンターコードを書き直す必要がなくなり、ウィンドウビューがコントロールのプレゼンターに情報を渡すためにモデルについて知る必要がなくなります。

これが効果的に行うことは、モジュールとしてのユーザーコントロールをデータモデルからさらに分離することです。これは、ユーザーコントロール全体を、ビュー実装の要素と考える場合に意味があります。再利用可能なユニットとして、これはビュー機能の一部であり、その一部をデータモデルに関連付けることはできません。

于 2009-01-15T01:25:20.897 に答える
0

あなたの質問は、さまざまなスキームが適用できる一般的なものです。

この場合、Observer Pattern を確認する必要があると思います。

そのビューを使用するものは何でも実装するインターフェイスがあります。次に、アプリケーションがそれらのインターフェイスのコレクションで初期化されるときに、それ自体を登録します。そのビューを更新する必要があるコマンドは、各ビューを更新する必要があることを通知するコレクションをトラバースします。

典型的な例とは異なり、ビューはユーザー コントロールになります。ユーザー コントロールに加えて、ダイアログ、完全なフォームなどを使用できるように、任意の UI 要素にそのインターフェイスを実装する柔軟性があります。

最後に、ユーザー コントロールはビューではなく、ビューの実装であることを思い出してください。採用するスキームに関係なく、必要なだけ深いビューを定義し、ユーザー コントロールにそのインターフェイスを実装させることができます。

于 2009-01-09T20:30:11.367 に答える