Should the view have nothing event specific in its interface and call the presenter plain methods to handle events and not have any official EventHandlers? For instance
// ASPX
protected void OnSaveButtonClicked(object sender, EventArgs e)
{
_Presenter.OnSave();
}
Or should the view have event EventHandlers defined in its interface and link those up explicitly to control events on the page
// View
public interface IView
{
...
event EventHandler Saved;
...
}
// ASPX Page implementing the view
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
SaveButton.Click += delegate { Saved(this, e); };
}
// Presenter
internal Presenter(IView view,IRepository repository)
{
_view = view;
_repository = repository;
view.Saved += Save;
}
The second seems like a whole lot of plumbing code to add all over.
My intention is to understand the benefits of each style and not just a blanket answer of which to use. My main goals is clarity and high value testability. Testability overall is important, but I wouldn't sacrifice design simplicity and clarity to be able to add another type of test that 开发者_运维问答doesn't lead to too much gain over the test cases already possible with a simpler design. If a design choice does off more testability please include an example (pseudo code is fine) of the type of test it can now offer so I can make my decision if I value that type of extra test enough. Thanks!
Update: Does my question need any further clarification?
I don't like having an explicit reference to a Button (or any other control) in the interface. This means we're tightly bound to the implementation of the control(s).
Controls can be implemented very differently between project types (Winforms and ASP for example).
This means the interface would potentially need to be modified for different views which is exactly what we don't want. The whole point of MVP is that the Presenter can rely on a stable interface which allows for separation of the UI from the model, easy substitution of concrete views and testability.
Better to stick with properties and methods on the interface which don't depend on any specific controls and leave the implementation details to the concrete views.
We've just implemented MVP using webforms, and opted for the simpler option of having the view call methods on the presenter directly for button events etc.
Our justification is that we are unable to unit test the view directly anyway (we use waitin for testing this layer), so the main goal here is to have a unit testable presenter which is separated as far as possible from the view/model.
From my experience, you're never going to achieve completely clean MVP in WebForms anyway due to the nature of the beast (they'd really love you to just use that code behind file...), so I wouldn't get hung up on it.
At the end of the day, you need to evaluate the reasons for separating out the view and presentation logic and determine whether either method is going to help/hinder you later on....
In your view's interface you should have a reference to the save button and then everything is done in the presentor. This keeps your view free of code and your preseneter easily testable.
// View interface
public interface IView
{
Button SaveButton;
}
// View code behind
public Button SaveButton
{
get { return btnSave; }
}
// Presenter
internal Presenter(IView view,IRepository repository)
{
_view = view;
_repository = repository;
view.SaveButton.Click += new EventHandler(Saved);;
}
void Saved(object sender, EventArgs e)
{
// do save
}
'
精彩评论