I’ve finally gotten together enough time to do some more work on TDDing User Interfaces and implementing the MVP pattern in .NET. As some of you know, I presented on a little bit of this at an MSDN Code Camp several months ago.
My flaw in that presentation was trying to cover too much ground. I tried to summarize everything from the Agile Manifesto to NUnit, NUnitAsp, TDD, TFUI, etc, etc. It was too much for a beginner crowd.
I promised myself I would come back around and do a fuller example from start to finish using TDD to generate a testable UI layer that also followed the MVP pattern. This afternoon I came up with an initial draft of the requirements.
So, first, the overall “hidden” goal is to end up with a testable UI/Presentation layer that allows different views to be plugged into it (including a Mock view). The views I’d like to see develop are thin wrappers around the UI specific code, and delegate immediately to the presentation logic. A good definition of MVP is available at Martin Fowler’s site, and also can be found in the discussion of the Humble Dialog (PDF).
Now, our “real” story is as follows:
The XYZ Realty Corporation, a state-wide realty corporation serving residential customers, has been having problems providing a consistant way for their realtors to be able to find home listings. Each realtor has an office, but some offices only have dial-up internet connections. Some realtors have laptops with internet access. A few have mobile phones that have internet access, and want to be able to search for homes on the phones which will help them when they are in a given area with a customer and want to see what is available around them.
After an initial meeting with the realtors, the following features came up:
- Search by one or more of:
- Area (Predefined based on geographical regions by the company)
- Zip Code
- Price Range
- Number of Bedrooms
- Square Footage
- Lot Size
- The form should be available over the internet and on the phones.
- The offices without high-speed connections should be able to download the latest listings and run a desktop app to search them.
- The listings should be sortable by each of the criteria
- An agent should be able to select a property and get the details of it, including address and pictures (if available, and if the device supports it)
The realtors, while busy, have agreed to be available to answer any questions that come along. Three key realtors have been identified who are the primary contacts:
- John Roberts, a realtor for 17 years. His office is on dial-up
- Susan Stern, a realtor for 9 years who does just about everything on her Blackberry
- David Craig, a realtor for 11 years who uses his laptop for access. He generally meets customers at Starbucks or his office to go over properties.
The database is a Microsoft SQL Server and is already populated and updated based on MLS Data and a custom in-house software package which lets them flag that properties are under contract or sold.
The company has an in-house web server running IIS 6.0. They have agreed that they are willing to upgrade any equipment if necessary.
From this, I intend to build out the application in installments, letting you see the warts along the way. I also would love feedback on the process. If there are things you think I should do differently, or things I’ve missed, please don’t hesitate to let me know.
I’ve struggled quite a bit with trying to build testable UI.
I eventually reached the point where I did mostly everything in MVP.
The problem is actually handling the UI display logic.
For instance, I’ve a remove button that should be enabled only when I’ve selected an item on a list.
What controls this behavior?
Well, it depends. Is that behavior part of a story? If it is, then it should be in your presentation logic.
However, here’s the catch. I generally advise against delving too heavily into seperating out presentation logic unless you have a need to have more than one view.
But, with that being said, the trick is to delegate everything to your presentation logic from the UI. So, in your case, you might have an object like PropertyListing, which is a list of the homes the user selected. And then a PropertyListingPresenter which handles interacting between the business object and your UI code through an interface. That interface might look like:
public interface IPropertyListingView
{
void SetPropertyListing(PropertyListing);
void PropertySelected(Property);
}
and your view implement it like:
protected void SetPropertyListing(
PropertyListing listings)
{
this.PropertyListDataGrid.DataSource = listings;
this.PropertyListDataGrid.DataBind();
}
protected void PropertyListDataGrid_ItemSelected(object sender, EventArgs e)
{
PropertySelected((Property)e);
}
So, again, you are just delegating everything to the Presenter class.
Does this help?