2012-04-30 35 views
7

我已經在一些使用被動視圖的WinForms應用程序中實現了MVP模式。我實現了一個包含屬性和代理的界面,其形式爲Action < T>和Func < T>以在具體視圖中連接UI事件並回叫主講者。MVP,Winforms - EventHandlers或代表

我即將開始一個新項目,並對線上模式進行了一些研究,包括模式的許多示例,並注意到所有人都使用EventHandler來通知演示者。

我不明白爲什麼會在這種情況下使用事件,因爲我認爲視圖只有一個演示者。

我的問題是,這是爲了與.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

你的模式在本質上是一樣的使用事件,一個關鍵的區別。事件不公開底層委託(ModelDataChangedCallback在你的例子中)。暴露這是不好的做法,因爲其他代碼可以清除調用列表。一個事件會有一個潛在的委託,可以添加或刪除,但從來沒有從班級範圍外清除。

我不明白你關於沒有多個訂戶的觀點 - 這不是不使用事件的理由。事件只是讓班級說「嗨!這件事已經發生」的一種方式,與Presenter對象進行1對1映射是完全合理和正常的。

您也不會在視圖中看到奇怪的只寫屬性。

+0

就只寫屬性達成一致,當我看到它們時會出現錯誤,併爲複雜視圖添加更多樣板代碼。 –

+0

但是,當使用事件時,他必須創建一個特定的'ModelDataChangedEventArgs'類來包含Presenter需要使用的數據,對嗎?當有很多事件發生時,鍋爐板類的數量將會爆炸。所有'動作 MyDelegate'必須改爲'EventHandler MyEvent' ...因爲它是1:1映射,所以清除調用列表的概率應該是非常有限的...... –