why we need to use MVP ?
• No Code Reuse - Each view (page/control) must create an instance of a specific presenter in order to invoke the presenter's methods. That's four or five lines of code per page/control; quite a bit of work if you have hundreds of pages and controls in your site. Code can and should be centralized.
• Presenter Creation - Presenters operate on a specific type of interface. Generally speaking, there's a one-to-one relationship between presenters and interfaces. This problem relates to the "no code reuse" point, and leads to inconsistent public-facing functionality exposed by various presenters. Object creation should be standardized.
• View Intelligence – Using the MVP pattern forces a view to know as much about its presenter (methods, properties etc…) as the presenter knows about its view. The use of interfaces prevents a circular reference, but there should still be further decoupling of the view. One area I may disagree with Bill is that views should also not know what data layer type (or DAO interface type) to pass to a presenter. I'm of the opinion that the view's shouldn't have a reference to any data layer (i.e. anything upstream of the presenters).
• State Management – This one is a biggie. Many of the people posting on MVP are quick to point out that (very simple) MPV examples remove the ability for ASP.NET to use session and caching. How do you access context-specific information if presenters can't have a reference to anything downstream (i.e. System.Web or System.Windows.Forms)? The presentation layer should provide a way to maintain application state.
======================
Here is a basic Contact Us Web Form that we'll build with the MVP Pattern.
The first step of MVP is to create a contract. We're going to use a .Net Interface for that. Create a file called IContactUs.cs and use this code. This is our VIEW in the MVP.
public interface IReaderContactUs
{
string Name { get; }
string Email { get; }
string PhoneNumber { get; }
string Message { get; }
string Result { set; }
}
The interface is like a blue print to a house. No implementation, just directions. This interface says that we have to be able to "GET" Name, Email, PhoneNumber, and Message. And that we have to be able to "SET" a Result string.
Next we need a Presenter. The presenter is the worker bee. The presenter actually does the work. Interestingly, the Presenter knows **NOTHING** about the UX. Repeat **NOTHING**. The presenter is usually in a different class library, and only referenced from the UX code. In order to enforce out contract (the .net interface we just created) we want to only be able to create a presenter, with an instance of the Interface. To do this, notice that our only constructor takes a single param that is the interface. Here is the code for our presenter; named ContactUsPresenter.cs
public class ContactUsPresenter
{
private readonly IReaderContactUs view;
public ContactUsPresenter(IReaderContactUs view)
{
this.view = view;
}
public void ProcessForm()
{
//do something - save it, send it, process it
//in this case, just modify the UI, so we
//know it's running.
//This is where you would normally make a call into the model
StringBuilder sb = new StringBuilder();
sb.Append(string.Format("Name : {0}<br />", view.Name));
sb.Append(string.Format("Email : {0}<br />", view.Email));
sb.Append(string.Format("Phone : {0}<br />", view.PhoneNumber));
sb.Append(string.Format("Message : {0}<br />", view.Message));
view.Result = string.Format("<h1>Success</h1>{0}<hr />", sb);
}
}
Finally we get to the code behind of our Web Form. Our web form Implements the Interface. All this means is that our web form has to be able to "GET" Name, Email, PhoneNumber, and Message. And that we have to be able to "SET" a Result string. Notice the appropriate Get / Set routines that wrap around the asp.net server controls.
Notice that we have a private ContactUsPresenter, that doesn't get instantiated until the OnInit event. This is because we have to send in an instance of the interface, which is the this keyword. Then when the button is clicked, the presenter.ProcessForm(); is called to do the work.
public partial class ContactUs : UserControl, IReaderContactUs
{
private ContactUsPresenter presenter;
public string Name { get { return NameTextBox.Text; } }
public string Email { get { return EmailTextBox.Text; } }
public string PhoneNumber { get { return PhoneTextBox.Text; } }
public string Message { get { return MessageTextBox.Text; } }
public string Result { set { ResultLabel.Text = value; } }
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
presenter = new ContactUsPresenter(this);
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SubmitContactButton_Click(object sender, EventArgs e)
{
presenter.ProcessForm();
}
}
=========
You may need to check out MVP Pattern in Web Client Software Factory as well. This will give you a complete guidance to implement MVP Pattern in your web application
http://www.codeplex.com/websf/Wiki/View.aspx?title=MVP_landing_page&referringTitle=bundles
No comments:
Post a Comment