Peelable UI’s

On pretty much every project, the subject of whether its feasible to perform unit testing (and indeed, TDD) at or near the user interface comes up. Over the last couple of projects the design that I find easiest to work has looked something like this:

public class SimpleView : ISimpleView {

private TextBox txtFirstname;
private Label message;
private Button okButton;

public string Firstname {
get { return txtFirstname.Text; }
set { txtFirstname.Text = value; }
}
public string Message {
set { message.Text = value; }
}

private void okButton_Clicked(object sender, EventArgs e)
{
controller.OkClicked();
}
}

public interface ISimpleView {
string Firstname { get; set; }
string Message { set; }
}

public class SimpleController {
private ISimpleView view;
public SimpleController(ISimpleView view) {
this.view = view;
}
public void OkClicked() {
string greeting = "Hello, " + view.Firstname + "!";
view.Message = greeting;
}
}

The general pattern is that any operation that requires the system to take action should be a method call to the controller, and that all the values from the view should be exposed on the interface. Widgets should not leak from the view into the controller. This approach allows for testing with NMock or JMock, as well as keeping the view classes so thin and logic-free that it is a simple task to peel off and replace with an alternative implementation (swapping thick client for web front end for example), or a test harness.