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


8

私は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-分離表示パターン/)。

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

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

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

編集:

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;
    }
}

回答:


6

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

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

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

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

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

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

あなたの編集:

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

備考3:このMSDNブログの作成者は、Martin Fowlerが行ったような他のアーキテクチャに関する包括的な詳細な記事を書くよりも、MVVMアーキテクチャを紹介することに関心があったと思います。また、.NETフレームワークの初期にさかのぼるMicrosoftのADOデータバインディングアーキテクチャは、このような混合設計を支持し、クラシックMVP を実装するのにそれほど簡単でなかったと思います(データモデルアクセスを分離するためにDataObjectSourceが必要でした)。


1
返信してくれてありがとう。質問を編集しました。MSDNの記事では、MVP監視コントローラーについて説明し、モデルがUpdatePersonalDataメソッドのパラメーターとして渡される場所を示しています。その後、そのメソッドはモデルを直接更新します。これは、「ビューがモデルを直接変更することはありません。モデルの変更は、常にプレゼンター(またはMVCのコントローラー)を介して行われます」と言うときに、あなたが言っていることと矛盾するようです。モデルがビューで更新されるという考えはあまり好きではありません。あなたの解釈には同意します。それは単なる解釈ですか?
エリック

1
@EricSこのMSDNブログ記事の作成者は、MVPの「データアクセス」という用語を双方向のデータバインディングとして誤って解釈したと思います。私はそれを強調するために私の答えを編集しました。
クリストフ

1
@EricSちなみに、ビューとモデル間のデータバインディングという用語は、Martin Fowlerの記事で制限されていることが確認されています。より複雑な相互作用に、コントローラが介入します。」
クリストフ

1
私はまだデータバインディングとそれが本当はそうであるかどうかについて頭を抱えています。データバインディングを実行するためのフレームワークがなければ、ゲッターとセッターを使用するだけでデータバインディングを実装できますか?その場合、一方向のデータバインディングのみを実装する場合は、モデルからデータを取得するゲッターのみを使用し、モデルは更新しません。代わりに、モデルの更新はプレゼンターに委任されます。
エリック

1

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

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

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

再び、Fowlerは記事の最後でこれについて話します:

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

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

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