Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Question moved from Stackoverflow - http://stackoverflow.com/questions/4971048/how-do-i-set-up-mvp-for-a-winforms-solution

I have used MVP and MVC in the past, and I prefer MVP as it controls the flow of execution so much better in my opinion.

I have created my infrastructure (datastore/repository classes) and use them without issue when hard coding sample data, so now I am moving onto the GUI and preparing my MVP.

Section A

  1. I have seen MVP using the view as the entry point, that is in the views constructor method it creates the presenter, which in turn creates the model, wiring up events as needed.

  2. I have also seen the presenter as the entry point, where a view, model and presenter are created, this presenter is then given a view and model object in its constructor to wire up the events.

  3. As in 2, but the model is not passed to the presenter. Instead the model is a static class where methods are called and responses returned directly.

Section B

In terms of keeping the view and model in sync I have seen.

  1. Whenever a value in the view in changed, i.e. TextChanged event in .Net/C#. This fires a DataChangedEvent which is passed through into the model, to keep it in sync at all times. And where the model changes, i.e. a background event it listens to, then the view is updated via the same idea of raising a DataChangedEvent. When a user wants to commit changes a SaveEvent it fires, passing through into the model to make the save. In this case the model mimics the view's data and processes actions.

  2. Similar to #b1, however the view does not sync with the model all the time. Instead when the user wants to commit changes, SaveEvent is fired and the presenter grabs the latest details and passes them into the model. in this case the model does not know about the views data until it is required to act upon it, in which case it is passed all the needed details.

Section C

Displaying of business objects in the view, i.e. a object (MyClass) not primitive data (int, double)

  1. The view has property fields for all its data that it will display as domain/business objects. Such as view.Animals exposes a IEnumerable<IAnimal> property, even though the view processes these into Nodes in a TreeView. Then for the selected animal it would expose SelectedAnimal as IAnimal property.

  2. The view has no knowledge of domain objects, it exposes property for primitive/framework (.Net/Java) included objects types only. In this instance the presenter will pass an adapter object the domain object, the adapter will then translate a given business object into the controls visible on the view. In this instance the adapter must have access to the actual controls on the view, not just any view so becomes more tightly coupled.

Section D

Multiple views used to create a single control. i.e. You have a complex view with a simple model like saving objects of different types. You could have a menu system at the side with each click on an item the appropriate controls are shown.

  1. You create one huge view, that contains all of the individual controls which are exposed via the views interface.

  2. You have several views. You have one view for the menu and a blank panel. This view creates the other views required but does not display them (visible = false), this view also implements the interface for each view it contains (i.e. child views) so it can expose to one presenter. The blank panel is filled with other views (Controls.Add(myview)) and ((myview.visible = true). The events raised in these "child"-views are handled by the parent view which in turn pass the event to the presenter, and visa versa for supplying events back down to child elements.

  3. Each view, be it the main parent or smaller child views are each wired into there own presenter and model. You can literately just drop a view control into an existing form and it will have the functionality ready, just needs wiring into a presenter behind the scenes.

Section E

Should everything have an interface, now based on how the MVP is done in the above examples will affect this answer as they might not be cross-compatible.

  1. Everything has an interface, the View, Presenter and Model. Each of these then obviously has a concrete implementation. Even if you only have one concrete view, model and presenter.

  2. The View and Model have an interface. This allows the views and models to differ. The presenter creates/is given view and model objects and it just serves to pass messages between them.

  3. Only the View has an interface. The Model has static methods and is not created, thus no need for an interface. If you want a different model, the presenter calls a different set of static class methods. Being static the Model has no link to the presenter.

Personal thoughts

From all the different variations I have presented (most I have probably used in some form) of which I am sure there are more. I prefer A3 as keeping business logic reusable outside just MVP, B2 for less data duplication and less events being fired. C1 for not adding in another class, sure it puts a small amount of non unit testable logic into a view (how a domain object is visualised) but this could be code reviewed, or simply viewed in the application. If the logic was complex I would agree to an adapter class but not in all cases. For section D, i feel D1 creates a view that is too big atleast for a menu example. I have used D2 and D3 before. Problem with D2 is you end up having to write lots of code to route events to and from the presenter to the correct child view, and its not drag/drop compatible, each new control needs more wiring in to support the single presenter. D3 is my prefered choice but adds in yet more classes as presenters and models to deal with the view, even if the view happens to be very simple or has no need to be reused. i think a mixture of D2 and D3 is best based on circumstances. As to section E, I think everything having an interface could be overkill I already do it for domain/business objects and often see no advantage in the "design" by doing so, but it does help in mocking objects in tests. Personally I would see E2 as a classic solution, although have seen E3 used in 2 projects I have worked on previously.

Question

Am I implementing MVP correctly? Is there a right way of going about it?

I've read Martin Fowler's work that has variations, and I remember when I first started doing MVC, I understood the concept, but could not originally work out where is the entry point, everything has its own function but what controls and creates the original set of MVC objects.

share|improve this question
    
The reason for asking this question is I am looking to get it right on almost the first attempt. I would rather have a standard MVP to follow, rather than create 6 applications using different variations for the same pattern. –  JonWillis Feb 14 '11 at 16:02
    
Perfect... I wanted to ask it for a long time –  The King Mar 21 '11 at 7:22

3 Answers 3

up vote 4 down vote accepted

A lot of what you present here is very reasonable and sound. Some of the choices are going to depend on specifics with the application and which one "feels" right. As is the case most of the time, there isn't going to be one right answer. Some of the choices will make sense here and those choices could be completely wrong for the next application and circumstances. Without knowing some of the specifics of the app, I think you are on the right track and have made some sound, thoughtful decisions.

For me, I feel that the Presenter should almost always be the entry point. Having the UI as the entry point puts too much logic in the UI and takes away the ability to substitute a new UI without big coding changes. And really that IS the job of the presenter.

share|improve this answer
    
Maybe the question I should ask are any of the ways to use MVP just plain wrong. I would agree with variations suit different scenarios, but feel there should be a generally accepted approach. The examples of MVP are all simple examples and nearly all with the same need, to edit a domain object and save changes. Yet from those examples with the same objective the above variations have been produced. I have just coded part of an app using events fired in the view to be handled in the presenter but I could have had the view hold a reference to the presenter and directly call methods. –  JonWillis Feb 14 '11 at 13:42
    
I would agree with all effort going to simplify the view to justify it not being unit tested, then the presenter should have control. My only concern with this (thinking in my head so could be wrong) is that say winforms/usercontrols may need to be linked to parent elements and wondered if additional logic is needed in a presenter to write it up. –  JonWillis Feb 14 '11 at 13:46
    
@Jon - Ways MVP are wrong? In my book it would be when the view knows about the presenter. It may not be "wrong" in the sense that it works but it just wouldn't be MVP, it's morphed into something else at that point. The problem with design patterns is that the examples are always as clean and simple as possible. Then when you go to implement them for the first time and the real world jumps up and says 'hey real apps are way more complicated than that puny example.' That's where your growth begins. Find what works for you and the app's circumstances. –  Walter Feb 14 '11 at 14:10
    
thanks for the advice. I remember learning MVC at university. Sounded great but with a blank canvas you wonder where to start and how it really works. In terms of MVP being wrong, I mean were any of the ideas/varitions of MVC I posted above the wrong way of doing it, i.e. when the view knows how the presenter works. Or should the view have a reference to an interface of a presenter or concrete type etc. Just many different variations which can all work for the same purpose. –  JonWillis Feb 14 '11 at 15:12
1  
@Jon - Your variations are all pretty much in keeping with the spirit of MVP. As far as working with interfaces or concrete types, it's going to depend on the circumstances of the app. If the app is fairly small, not very complex, then perhaps adding interfaces isn't necessary. I like to keep things as simple as possible, until it's quite clear that the app absolutely needs to implement X architecture. See this answer for more detail: programmers.stackexchange.com/questions/34547/… –  Walter Feb 14 '11 at 17:34

We use a modified form of MVP on our .NET 2.0 Winforms app. The two pieces we were missing were a modified adapter of the WPF ViewModel, and adding data binding. Our specific pattern is MVPVM.

We wire in as presenter-first in almost every case, except for custom usercontrols, which are wired in view-first for designer friendlyness. We use dependency injection, code-generated ViewModels, BDD for the presenters, and TDD/TED for the model.

The VM's are just a massive, flat, wad of properties that raise PropertyChanged when they're changed. It was very easy to generate these by code (and their associated exercising unit tests). We use them for reading and writing to user-interactable controls, and controlling enabled statuses. The ViewModel is coupled with the View, since we use databinding for damn near everything else.

The View will occasionally have methods on it to accomplish things that the VM can't. This is usually controlling visibility of items (WinForms can be picky about it), and things that refuse to be databound. The View always exposes events like "Login" or "Restart", with appropriate EventArgs to act on user behaviors. Unless we've had to use a hack like "View.ShowLoginBox", the View is completely interchangable as long as it meets the general design requirements.

It took us about 6-8 months to nail down this pattern. It has a lot of pieces, but is very flexible and extremely powerful. Our specific implementation is very asynchronous and event-driven, which may just be an artifact of other requirements rather than a side-effect of the design behavior. For instance, I added thread synchronization to the baseclass that our VM's inherit from (which simply exposed an OnPropertyChanged method to raise the event) -- and poof, now we can have multithreaded presenters and models.

share|improve this answer
    
I know your MVPVM may be of commercial interest, but if its okay could you provide any sample code? On a side note, where do you draw the line on what does in the model and what goes in the presenter. I've seen presenter be so basic they handle view events and just call the model, to the presenter accessing the data layers to pass business objects to a model, all the way upto the model being replaced by the presenter. –  JonWillis Feb 16 '11 at 8:28
    
Yep, let me finish up an example. It will be tailored slightly towards our business, since I'm using it as an in-house training tool. –  insta Feb 17 '11 at 16:14
2  
pingring.org/DesignPatternSample.7z Requires VS2010, and Rhino Mocks. –  insta Feb 17 '11 at 19:02
    
Thank you, I will look over it on the weekend to see if I understand it –  JonWillis Feb 18 '11 at 14:51

I am using a version of PureMvc that's been modified for .Net, and then extended by myself.

I was used to PureMvc from using it in Flex applications. It is a bare bones type of framework so its fairly easy to adapt if you want to customize it.

I took the following liberties with it:

  • Using reflection I was able to get private properties in the view-mediator to go out into the form class and grab the (private) reference to each control I was mediating.
  • Using reflection I can auto-wire the controls to the event signatures in my mediator, which are generic, so I just switch on the sender parameter.
  • Normally, PureMvc wants derived mediators to define their notification interests in a function that will return an array of strings. Since my interests are mostly static, and I wanted to have an easier way to see the mediators interests, I did a modification so that the mediator can also declare its interests by set of member variables with a particular signature: _ _ _<classname> _ <notification-name>. This way I can see what is going on using the IDE member tree instead of looking inside a function.

In PureMvc, you can use a Command to be the entry point, a typical Start command would set up the Model to the extent it could, then create the MainForm, create and register the mediator for and with that form, then do Application.Run on the form.

The mediator for the form would be responsible for setting up all the sub-mediators, some of this can be automated by, again, using reflection tricks.

The system I am using is drag/drop compatible, if I understand your meaning. The actual form is all created in VS, but my experience is only with forms that have statically created controls. Things like dynamically created menu items seem feasible with a bit of tweaking of the mediator for that menu or submenu. Where it would get hairy is when the mediator had no static root element to be hooked onto and you got into creating dynamic 'instance' mediators.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.