Model View Presenter Pattern - User Interface Design Patterns

Model-View-Presenter Pattern - User Interface Design Patterns

by David Hayden ( ASP.NET Developer )

 

I was reading a few blog posts today and noticed that Scott Cate gave a presentation on the Model View Presenter Pattern at the Florida.NET User Group. According to his post, it looks like he rocked the house. I am envious here in Sarasota, wishing I could have seen the presentation for which he provided the source code.

Still, I feel like I was there, because I downloaded the source code to see what he had built from scratch during the presentation. If you are new to the Model View Presenter Pattern and looking for a gentle introduction to it, I highly recomment looking at the source code. Scott uses table adapters for data access and uses the ASP.NET Page as the view. Simple and straight forward without adding a lot of extra fat to make the subject more complex than it has to be. Great job, Scott. Maybe we can get you to Sarasota for a similar presentation.

I played with Scott's source code a bit, evolving it into something that I could unit test. This isn't necessary, but I enjoyed the exercise :) Right now as the Presenter class stands, it is tied directly to the table adapter that retrieves data:

 

namespace MiramarFAQ.Presenter
{
    public class RetrieveFaqPresenter
    {
        private readonly IRetrieveFaqView view;
        
        public RetrieveFaqPresenter (IRetrieveFaqView view)
        {
            this.view = view;
        }
        
        public void RetrieveFAQ()
        {
            FaqTableAdapter adapter = new FaqTableAdapter();
            DataTable faq = adapter.GetDataByFaqId( view.FaqId );
            
            //...
        }
    }
}

 

I changed the Presenter code a bit so it looked like this:

 

namespace MiramarFAQ.Presenter
{
    public class RetrieveFaqPresenter
    {
        private readonly IRetrieveFaqView view;
        private readonly IFaqDataService service;

        public RetrieveFaqPresenter(IRetrieveFaqView view) :
            this(view, new SqlFaqDataService()) { }

        public RetrieveFaqPresenter(IRetrieveFaqView view,
IFaqDataService service) {
this.view = view; this.service = service; } public void RetrieveFAQ() { DataTable faq = service.GetDataByFaqId(view.FaqId); //... } } }

 

All I have done is introduced an IFaqDataService as a dependency to the presenter as oppose to hardcoding the TableAdapter in the code. This gives me a bit more pluggability of the data access layer as well as offers more testability.

 

namespace MiramarFAQ.Data
{
    public interface IFaqDataService
    {
        DataTable GetDataByFaqId(int FaqId);
    }
}

 

namespace MiramarFAQ.Data
{
    public class SqlFaqDataService : IFaqDataService
    {
        #region IFaqDataService Members

        public DataTable GetDataByFaqId(int FaqId)
        {
            FaqTableAdapter adapter = new FaqTableAdapter();
            return adapter.GetDataByFaqId(FaqId);
        }

        #endregion
    }
}

 

Now that we have introduced a dependency on only an interface, IFaqDataService, in the presenter class, we can create a stub for our unit testing:

 

public class StubbedFaqDataService : IFaqDataService
{
    #region IFaqDataService Members

    public DataTable GetDataByFaqId(int FaqId)
    {
        Faq.FaqDataTable dt = new Faq.FaqDataTable();
        dt.AddFaqRow("Title", "Body", "Author", "tag1,tag2",
"testing...", DateTime.Now); return dt; } #endregion }

 

I won't bore you with details of the unit tests, but you can see where all of this takes you. You lose that dependency on TableAdapters, and focus your dependency on an interface ( contract ), called IFaqDataService. This opens the doorway for pluggable data access services, dependency injection, and unit testing.

Again, I wish I could have been there for Scott's presentation on Model View Presenter, because the code only tells half of the story. I bet the dialogue was fantastic. Thanks to all the INETA speakers who devote time to helping the community. Thanks to Scott for sharing his code so I could vicariously be there via Sarasota, Florida. Don't forget to check out Scott's source code.

 

Other Resources

In addition to Scott Cate's wonderful example, here are a number of great articles by some very smart people:

 

Source: David Hayden ( ASP.NET Developer )

Filed: Design Patterns

 

posted on Wednesday, September 13, 2006 5:27 PM

Main

News

Green Tea

.NET Development

Enterprise Library

Patterns & Practices