Over the weekend I did a lot of reading about the Model/View/Presenter development paradigm, and tried my hand at a few coding examples.

The idea behind MVP is that you take all the logic that would normally tie your user interface (the View) to your data (things like populating TextBox controls, or validating user input) and move it back into a class of its own (the Presenter). This means that your UI (Forms, UserControls etc) becomes very "thin", and can easily be swapped out for some other design.

Since the logic of the program isn't tied up in the UI, MVP also makes it easy to design a test framework to make sure your business logic is sound.

In a way, it's almost like MVP is a replacement for data binding. It's a little more code, but could be worth the effort in the long run.

The example I was playing with at home was a way to view a "folder" in Comicster. A folder only has two properties - an ID (a Guid) and a Name (a string), so it's a pretty simple thing to view on the screen. I started by creating a simple class to represent the folder:

public class Folder { public Folder() : this(Guid.NewGuid()) { } public Folder(Guid id) { _id = id _name = "New Folder"; } private Guid _id; private string _name; public Guid ID { get { return _id; } set { _id = value; } } public string Name { get { return _name; } set { _name = value; } } } 

So now I had a "model" to work with. In reality this would probably be a FoldersDataRow - a row from the Folders table in my typed DataSet.

Next I had to create the interface that my "view" would implement. Again, the idea of MVP is that the view is pretty dumb and easily replaceable, so it shouldn't need to know too much about the implementation of other parts of the program. The view interface, then, just needs to look like this:

public interface IFolderView { Guid ID { get; set; } string Name { get; set; } event EventHandler Update; } 

I've included an "Update" event in that interface so that the UI has some way of notifying the presenter that the user wants to update the folder. For example, the user has changed the folder name TextBox and clicked the OK button.

Next I need to create a form that implements this interface, so that the presenter layer has something to talk to. I just whacked a TextBox and a Button on there and ended up with something like this:

public partial class FolderForm : Form, IFolderView { /* ... */ private void button1_Click(object sender, EventArgs e) { if (Update != null) { Update(this, e); DialogResult = DialogResult.OK; } } private Guid _id; public Guid ID { get { return _id; } set { _id = value; } } public string IFolder.Name { get { return textBox1.Text; } set { textBox1.Text = value; } } public event EventHandler Update; } 

This form, then, is just a dumb way of displaying the individual parts of a folder. It doesn't know anything about the "Folder" class (or FoldersDataRow, or whatever).

The last piece of the puzzle is the presenter - the class that takes a folder and tells the UI about it:

public class FolderPresenter { public FolderPresenter(Folder folder, IFolderView view) { _folder = folder; _view = view; _view.Update += UpdateFolder; } private Folder _folder; private IFolderView _view; public void Initialize() { _view.ID = _folder.ID; _view.Name = _folder.Name; } public void UpdateFolder(object sender, EventArgs e) { _folder.ID = _view.ID; _folder.Name = _view.Name; } } 

So this "FolderPresenter" class is constructed with an instance of a folder, and a way to view that folder. It can then populate the view with the details of the folder. The view doesn't have to know that the folder is represented in the model as a Folder class - it just has to know that the folder has an ID and a Name.

In our main form, then, where we have a folder and want to show the "edit folder" dialog, we do something along these lines:

 private void ShowFolder(Folder folder) { FolderForm f = new FolderForm(); FolderPresenter p = new FolderPresenter(folder, f); p.Initialize(); f.ShowDialog(); } 

And we're done!

Now, I still have some questions about this methodology. Like, what's the best way to present the user (the view) with a list of objects (a grid, for example)? And how much logic can I pull out of the view? For example, if I can edit or delete a folder, should I have a presenter that handles that, too? Maybe a "ViewFolderPresenter" which knows how to edit and delete a folder, and if you want to edit it it does the work of creating an "EditFolderPresenter" etc.

I will definitely kick on with the idea and see where it leads. It seems like a great way to build a UI using current technologies (Windows Forms or ASP.NET) and be able to swap in something more advanced (WPF or WPF/E) later on.

I recommend checking out Jean Paul Boodhoo's DNRTV episode on MVP, too. It was the first time I'd seen anything about the pattern.