web-dev-qa-db-ja.com

MVP(監視コントローラー)ビューはモデルを更新しますか?

私はMVPについて、特にコントローラーの監督について読んでいます。ビューをモデルとどのようにやり取りするかは、頭を抱え込むのが難しいことの1つです。

プレゼンターがモデルを更新する必要があり、ビューがモデルから読み取ることは私の理解でした。プレゼンターは、インターフェイスを介してビューを更新することもできます。これに関するマーティンファウラーの記事は、それだけを示しているようです( http://martinfowler.com/eaaDev/SupervisingPresenter.html )。

ただし、他の記事/ブログは、モデルを直接更新するビューを示しています( https://blogs.msdn.Microsoft.com/erwinvandervalk/2009/08/14/the-difference-between-model-view-viewmodel- and-other-separated-presentation-patterns / )。

これらは単なるパターンであることを知っているので、さまざまな実装がありますが、モデルを更新するビューは、必要以上に多くのことをしているようです。

たとえば、名前と電話番号を含む人物クラスがあったとします。ビューには、この名前と番号、および個人の名前と番号を変更するための送信ボタンを表示できます。送信ボタンをクリックすると、ビューではなくプレゼンターで更新が処理されると思います。ただし、私が参照した記事は、ビューがモデルを直接更新できることを提案しています。

それで、ビューはモデルを更新する必要がありますか?それとも、プレゼンターだけが処理する必要がありますか?

編集:

MSDN記事のコード:

public class PersonalDataView : UserControl, IPersonalDataView
{
    protected TextBox _firstNameTextBox;

    public void SetPersonalData(PersonalData data)
    {
        _firstNameTextBox.Value = data.FirstName;
    }

    public void UpdatePersonalData(PersonalData data)
    {
        data.FirstName = _firstNameTextBox.Value;
    }
}
8
Eric

1996年の元の設計はMike Potelによる 以来、MVPにはいくつかのバリエーションがあります。 Martin Fowlerがそれらのいくつかを別の GUIアーキテクチャに関する記事 で説明しています。

バリアント間の主な違いの1つは、ビューがモデルから完全に isolated であるかどうかです。

  • 最初のケースでは、プレゼンターは「パッシブビュー」とモデルの真ん中にいる男性です。
  • 2番目のケースでは、プレゼンターは「監視コントローラー」ですが、ビューとモデルの間には直接相互作用があります。 Potelのペーパーでは、相互作用の種類について詳しく説明しています。ビューはモデルからデータを要求でき、モデルはビューにいくつかのイベントを通知できます。

いずれの場合も、ビューがモデルを直接変更することはありません。モデルの変更は、常にプレゼンター(またはMVCのコントローラー)を介して行われます。

備考1:MSDNの記事では、MVC(Model View Controller)パートの紹介で、ビューからモデルに直接向かう矢印が1つだけ示されています。矢印は間違った方向にありますが、テキストは正しいです。ビューはモデルにアクセスでき、モデルのデータが変更されるとそれ自体を変更できます(つまり、モデルではなく、自分自身を再描画します)。

備考2:MSDNの記事には、おおよそMVPであるMicrosoftのMVVMパターンも示されていますが、プレゼンターは「ViewModel」とあいまいに呼ばれています。ただし、ここでも、ビューはモデルを直接更新しません。

あなたの編集:

編集のコードは双方向のデータバインディングを示しています。ビューのデータを更新すると、モデルの変更が直接トリガーされます。これは、ビューがプレゼンターに「インタラクター」を介して必要な変更を通知し、プレゼンターが「コマンド」を呼び出してモデルを更新する独占権を持っている元のMVPパターンと実際に矛盾します。

注釈3:このMSDNブログの作成者は、Martin Fowlerが行ったような他のアーキテクチャに関する包括的な詳細な記事を書くよりも、MVVMアーキテクチャの紹介に興味を持っていたと思います。また、Microsoftの [〜#〜] ado [〜#〜] .netフレームワークの初期にさかのぼるデータバインディングアーキテクチャは、このような混合設計を支持し、古典的なMVPを作成したと思います それほど重要ではない 実装する(データモデルへのアクセスを分離するにはDataObjectSourceが必要だった)。

6
Christophe

質問でリンクしたFowlerの監督プレゼンターの記事から:

UIをビューとコントローラーに分解します。ビューは、基になるモデルへの単純なマッピングを処理し、コントローラーは入力応答と複雑なビューロジックを処理します。

すべての単純なタスクについて、ビューはモデルと直接対話できることを明確に述べています。したがって、MSDNの記事と矛盾しません。これは、プロパティの単純なマッピング/バインディングの場合、別のレイヤーを使用する必要がないためです。これは、複雑さを増すだけで多くの利点がなくなるためです。

再び、ファウラーは記事の最後でこれについて話します:

[...]運転の問題は、ビューに残す行動の量です。パッシブビューは、スーパーバイザーコントローラーと非常によく似たパターンですが、単純なケースを含め、すべてのビュー更新動作をコントローラーに配置する点が異なります。これにより余分なプログラミングが発生しますが、すべてのプレゼンテーション動作がテスト可能であることを意味します。 2つのどちらを選択するかは、使用しているデータバインディングサポートの種類と、コントローラーテストでテストせずにそのままにしておくかどうかによって異なります。

いくつかの点に注意してください。

  • モデルが常にそのデータの「マスター」であることを確認してください。つまり、ビューはモデルのフィールドに直接書き込むべきではありません(とにかく悪い考えです)。あなたの言語がそれらをサポートしていれば、プロパティは問題ありません。このようにして、モデルはデータの更新に反応できます(別のフィールドを計算するなど)。
  • モデルをビューに結合しないでください。モデルは独立してテスト可能でなければならず、原則として、モデルに影響を与えずにビューを変更できる必要があります。つまり、モデルがビューを直接呼び出すことはありません。インターフェース、またはおそらくここで最も良いオブザーバーパターンを使用します。ビューは、更新のために自分自身をモデルにサブスクライブできます。
  • (ビジネス)ロジックをビューに配置しないでください。ビューコードでifステートメントを記述している場合は、それらがプレゼンターまたはモデルに属すべきかどうかを検討してください。
1
jhyot