views:

135

answers:

3

I'm re-working a Winforms application and would like to employ a variation of the Presentation Model pattern for the UI. Could someone tell me from the following explanations if I'm doing it correctly?


I have decided to set up dependencies as follows:

   Model <---- Presentation Model <---- View

That is:

  • The model is not aware of anything except itself.

  • The presentation model has a reference to the model (but not vice versa).

  • The view has a reference to the presentation model (but not vice versa).

I am using Winforms data binding to keep the view and the presentation model synchronised.

Now this all works like a charm, except when I need to deal with e.g. a click on a form's "Close" button. Since the presentation model has no reference to the view, it cannot subscribe to any events published by the view. Thus I've come up with the following crutch:

Presentation Model                   View
+--+                                 +--+
|  |                                 |  |
|  |                                 | <--------X closeButton.Click event fires
|  |                                 |  |
|  |                         +--------X |
|  |   CloseRequested = true |       |  | 
|  |                         +--------> |
|  |                                 |  |
|  | CloseRequested   CloseRequested |  |
| <-----------------------------------< |
|  |                                 |  |
| X--------+                         |  |
|  |       | IsClosed = true         |  |
| <--------+                         |  |
|  |                                 |  |
|  | IsClosed              MustClose |  |
| >-----------------------------------> |
|  |                                 |  |
|  |                                 | X--------> view.Close()
|  |                                 |  |
+--+                                 +--+

That is:

  • The user clicks the "Close" button.

  • The button's Click event is captured in the view, which reacts by setting the property CloseRequested.

  • Data binding transfers this value to a corresponding property in the presentation model.

  • The presentation model reacts to this change by setting its property IsClosed.

  • Data binding transfers this value into the view's MustClose.

  • The view reacts to this change by closing itself.

The presentation model is quite nicely decoupled from the view, and vice versa, however this is a lot of work only to process a single button command. Is there an easier way, given the dependency graph I've decided on?

+2  A: 

I've recently been converting a Windows Forms application to the MVP architecture, and it looks like you've set up your dependencies in a similar way to what I've been doing. However, I simply have an IPresenter interface which defines methods to allow the view to pass on user requests. As the view already has a dependency on the presenter and a reference to it, it seems sensible to simply call request methods on it directly.

So in my system, the presenter listens to events from the model and fires its own presentation events for any interested view to listen out for. The view responds to those events by updating itself as appropriate, and forwards user requests to the presenter when they are made.

Rich
A: 

The view has a reference to the presentation model (but not vice versa).

AFAIK the presentation should have a refference to view more exactly to interface IView so that the presentation dosen't couple with concrete view. Then in presentation class you may call view methods and subscribe to view events via IView.

Arseny
There are many variations on MVP, and I've seen both ways done. In the approach you describe, the presenter will have a dependency both on the model and IView. Additionally, all views will be *required* to implement all IView methods, even ones they don't handle or care about. In this approach, the presenter only depends on the model, and the view only depends on the presenter.
Rich
no, presentation model is different approach than MPV. Thread Starter is right presentation model should not has reference to UI because it should be easy to unit testing.
ktutnik
@ktutnik as I wrote Presenter got reference to IView interface not a View control so that it is possible to Unit test Presenter class.
Arseny
@Arseny yes i see and you are right in context of MVP!, but regarding Martin's Fowler, Presentation Model only consist of View, PresentationModel and Model, presentation model is different than Presenter, presentation model updates view by notification via data binding but not directly update the view. it is a no-no to have reference of ui because it is an evolution of Model. ;)
ktutnik
+1  A: 

it is only my opinion.

Working with presentation model require 100% UI support for data binding. Even WPF don't make the CLOSE action as Bindable. A lot of thing will not working smoothly in presentation model such as MessageBox Confirmation. even it can be abstracted with Presenter interface but still doesn't taste good and simplicity is sacrificed.

in the other hand, the main purposes of presentation model is to Test The View Logic. In some cases if your "Close Action" should be unit tested because of there is some logic before it is close then your code is the only choice. but if it is only a simple Confirmation "Are you sure you want to quit" then you better put that on the View not in presentation model because it is not require to unit test.

ktutnik
I'm aware that data binding in Winforms is not perfect. (For example, it is only available for UI controls, not for POCOs. Also, as the name implies, it supports only properties but not events.) But it this truly the fundamental problem when implementing any flavour of the MVP pattern in Winforms?
stakx
Yes! because the fundamental is Binding. In WPF it is called MVVM (Model - View - View Model) and Adobe Flex it is called (Presentation Model). you can try to search **dialog confirmation mvvm** or **flex validation presentation model** you will see how Presentation Model Pattern brings more trouble either than clarity. Im not saying it is a Bad Pattern but to make it 100% work it is require 100% View Support for databinding. Remember MVP and presentation Model is different take a look at http://nirajrules.wordpress.com/2009/07/18/mvc-vs-mvp-vs-mvvm/
ktutnik