How do I set up MVP for a Winforms solution?
Posted
by
JonWillis
on Programmers
See other posts from Programmers
or by JonWillis
Published on 2011-02-14T09:14:18Z
Indexed on
2011/02/14
15:34 UTC
Read the original article
Hit count: 547
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
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.
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.
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.
Whenever a value in the view in changed, i.e.
TextChanged
event in .Net/C#. This fires aDataChangedEvent
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 aDataChangedEvent
. When a user wants to commit changes aSaveEvent
it fires, passing through into the model to make the save. In this case the model mimics the view's data and processes actions.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)
The view has property fields for all its data that it will display as domain/business objects. Such as
view.Animals
exposes aIEnumerable<IAnimal>
property, even though the view processes these into Nodes in a TreeView. Then for the selected animal it would exposeSelectedAnimal
asIAnimal
property.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.
You create one huge view, that contains all of the individual controls which are exposed via the views interface.
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.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.
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.
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.
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.
© Programmers or respective owner