7

パッシブ ビューを使用するいくつかの WinForms アプリケーションに MVP パターンを実装しました。プロパティとデリゲートを含むインターフェイスを Action< T > と Func< T > の形式で実装して、具体的なビューで UI イベントを接続し、プレゼンターにコールバックします。

私は新しいプロジェクトを開始しようとしています。ここにパターンの多くの例を含め、パターンをオンラインで少し調査しましたが、すべて EventHandler を使用してプレゼンターに通知していることに気付きました。

ビューにはプレゼンターが 1 つしかないので、この場合にイベントが使用される理由がよくわかりません。

私の質問は、.Net フレームワークがイベントを使用する方法と一貫性を保つためですか、それとも私が見ていない他の理由のためですか?

私が使用するパターンの簡単な例を次に示します。

public interface IViewAbstraction
{
    public ModelData ModelData { set; }
    public Action<ModelData> ModelDataChangedCallback { set; }
}

public class SomeWinForm : Form, IViewAbstraction
{
    private Action<ModelData> modelDataChanged;
    private ModelData model;

    public ModelData ModelData
    {
        set { /* when this property changes, update UI */ }
    }

    public Action<ModelData> ModelDataChangedCallback
    {
        set { modelDataChanged = value; }
    }

    private void OnSomeWinformsEvent(EventArgs args)
    {
        if (modelDataChanged == null) throw new Exception();

        modelDataChanged(model);
    }
}

public class Presenter
{
    private readonly IViewAbstraction view;
    private readonly IDataLayerAbstraction dataLayer;

    public Presenter(IViewAbstraction view, IDataLayerAbstraction dataLayer)
    {
        this.dataLayer = dataLayer;
        this.view = view;
        this.view.ModelDataChangedCallback = OnModelChanged;
        this.view.ModelData = dataLayer.GetData();
    }

    private void OnModelChanged(ModelData data)
    {
        // validate and save data.
    }
}
4

1 に答える 1

5

あなたのパターンは基本的にイベントを使用する場合と同じですが、重要な違いがあります。イベントは、基になるデリゲート (例では ModelDataChangedCallback) を公開しません。たとえば、他のコードが呼び出しリストをクリアできるため、これを公開することは悪い習慣です。イベントには、追加または削除できる基になるデリゲートがありますが、クラスのスコープ外から削除することはできません。

複数のサブスクライバーを持たないというあなたの主張がわかりません。これは、イベントを使用しない理由ではありません。イベントは、クラスが「やあ、これが起こった」と言う方法にすぎません。Presenter オブジェクトとの 1 対 1 のマッピングは、完全に合理的で正常です。

また、ビュー内のかなり奇妙に見える書き込み専用プロパティで終わることもありません。

于 2012-05-01T06:42:07.663 に答える