none
Advantages of the MVP design pattern with delegates used my Microsoft samples versus direct call presenter.Method() ? RRS feed

  • Question

  • Hello,

    with MVP design pattern you pass the view of type Interface to the presenter`s constructor and then you access the data in the View via view.FirstName;

    When I look at many Microsoft samples they also declare delegates + events in the view interface and register those events in the presenter`s constructor like
    view.AddCustomerEvent += View_AddCustomer();

    Where is the advantage from the Microsoft version of MVP ? Why should I write all that delegate/event stuff which is much much more work when I could do a simple

    presenter.AddCustomer() method call within the View and in the presenter I get the data like this:

    public void AddCustomer()
    {

       _customerRepository.AddCustomer(new Customer()
       {
           FirstName = _view.FirstName,
           LastName = _view.LastName,
       });

    }

    It would really interest me wherein the advantage of the Microsoft interpretation lies! I would be pleased about an answer :)
    Monday, September 21, 2009 8:19 AM

Answers

  • Hi,

    This I feel is about dependencies between the presenter and the view. The view shouldn't need to know what type of presenter is controlling it, however the presenter does need to know what views it controls.

    If the view calls 'presenter.AddCustomer()' then the view knows about the presenter and that presenter cannot be changed very easy because of the dependency between them. For example you cannot change the presenter to something that doesn't have an AddCustomer method. Ok you might think you never will need to do this, and if that is the case, then your ok...

    However by using events many presenters can be notified of the view events and presenters can be changed very easily as the views and the presenters are losely coupled. The view just raises the event and forgets about it.


    So with the view calling the presenter it's a one to one relationship and that relationship is highly dependent on each other and with the events approach it a one to many relationship where the view and presenter are less dependent on each other and that makes thing easier to change.


    Lets imagine in your situation that when the add customer button is pressed then a customer is added and an audit log is recorded.

    With the view calling the presenter method then the presenter needs to do two things, it needs to add the customer and it needs to add the audit log entry. The method AddCustomer() does two things now, ok you think, but it goes against the SOLID principles (Single Responsibility)... but it's not the end of the world (until you want to audit the record to file as well as to a database). One controller is accessed from one event.

    Lets take the other example of raising an event. The view raises the AddCustomer event which both the DatabaseController and AuditController are listening for. The DatabaseController takes the customer data and adds the customer to the database while the AuditController takes the customer data and stores the audit record to file. The two 'features' are more seperate in this approach and can be changed more easier.  The two controllers react to one event.


    There are no correct answers here. If you feel one approach is better for you in certain circumstances then use it. To be honest with you I'd be more inclined to use the events approach as it lends itself more to unknown future changes. I always like my classes to be independant.

    Hope that helps.
    www.dsmyth.net | www.dsmyth.net/wiki
    • Marked as answer by Lisa Tatum Monday, September 21, 2009 11:43 AM
    Monday, September 21, 2009 11:18 AM

All replies

  • Hello,

    The advantage lies in the fact that in your example the presenter is completely passive to the UI, you can't pass anything back and forth to the UI, meaning it's unidirectional.

    When you're using events you can delegate the work and information to the presenter to inform the model.

    Now, in your example the only way to go back and forth I'll probably have to expand the method to accept arguments which already makes this approach complicated, imagine I want to pass some arbitrarily method that uses some values from within the presenter ? in this case I'll have to pass a method and execute it on the parent method, like so.

    Code Snippet
    1. public static int Multiply(BinaryOp binaryOp) {
    2.             return binaryOp(a, b);
    3.         }

    Now going farther what if we have a really complicated presenter-view relationships ? we gonna end up with far worst complicated paradigm, that may not be so usable.

    Events ease this by doing everything directly on the view, if you need any information from the presenter it's always available through the event arguments, it decouples the view from the presenter.

    In the end it's slightly more complicated, but it save you a lot of headache in the long-run. :)

    edit: I forgot to add, you can actually simplify things and use delegates without the use of events but then you lose three important things.

    * Events operates upon the object's level rather than the class level.
    * Events can be declared in interfaces.
    * Event can have add, and remove methods a.k.a accessor methods.


    Eyal, Regards.

    blog.eyalsh.net
    Monday, September 21, 2009 9:47 AM
    Moderator
  • Hello,

    The advantage lies in the fact that in your example the presenter is completely passive to the UI, you can't pass anything back and forth to the UI, meaning it's unidirectional.

    But thats not true. My presenter is not completely passive to the UI because I get data form the view via _view.FirstName; and I rebind data to the view via _view.BindCustomer(customer);

    so my presenter gets/sets UI data

    I even found and lost a msdn magazie article where jean Boodoo afair says not to pass any data to stuff like this presenter.AddCustomer(...); but he says using presenter.AddCustomer() is ok. The AddCustomer is just my sample method...

    if the presenter object is already created in the View why not use it and build up a big architecture with inflexble stuff like delegates in interfac, view implements those delegates, call the delegates via if (AddCustomerEvent != null) how boring... and then call AddCustomerEvent();

    I see no advantage with delegates. Not in my database driven desktop application.
    Monday, September 21, 2009 10:06 AM
  • Ok, this can work, but you still lose on flexibility, what if I want to do some arbitrarily operation with your approach, you're bound to the method signature, I cannot operate on the context, unless in your method signature you allow to pass a method, which you already one step closer to have an event by declaring a delegate.


    Eyal, Regards.

    blog.eyalsh.net
    Monday, September 21, 2009 10:27 AM
    Moderator
  • hm... but why should I want to pass a method as method parameter?

    I call this from my view:

    presenter.AddCustomer();
    presenter.DeleteCustomer();
    presenter.UpdateCustomer();
    whatever...

    so why should I pass them methods or pass them something at all?

    Could you please post me some of the arbitrarily operation as code sample you would like to do with my approach , just show me where I lose flexibility as I do not fully understand your statement technically ;-)

    see this msdn article: jean-paul boodhoo said:

    This event handler ensures that whenever a new customer is selected in the dropdown, the view will ask the presenter to display the details for that customer.
    It is important to note that this is typical behavior. When a view asks a presenter to do something, it asks without giving any specific details, and it is up to the presenter to return to the view and get any information it needs using the view interface.
    http://msdn.microsoft.com/en-us/magazine/cc188690.aspx
    Monday, September 21, 2009 10:36 AM
  • Hi,

    This I feel is about dependencies between the presenter and the view. The view shouldn't need to know what type of presenter is controlling it, however the presenter does need to know what views it controls.

    If the view calls 'presenter.AddCustomer()' then the view knows about the presenter and that presenter cannot be changed very easy because of the dependency between them. For example you cannot change the presenter to something that doesn't have an AddCustomer method. Ok you might think you never will need to do this, and if that is the case, then your ok...

    However by using events many presenters can be notified of the view events and presenters can be changed very easily as the views and the presenters are losely coupled. The view just raises the event and forgets about it.


    So with the view calling the presenter it's a one to one relationship and that relationship is highly dependent on each other and with the events approach it a one to many relationship where the view and presenter are less dependent on each other and that makes thing easier to change.


    Lets imagine in your situation that when the add customer button is pressed then a customer is added and an audit log is recorded.

    With the view calling the presenter method then the presenter needs to do two things, it needs to add the customer and it needs to add the audit log entry. The method AddCustomer() does two things now, ok you think, but it goes against the SOLID principles (Single Responsibility)... but it's not the end of the world (until you want to audit the record to file as well as to a database). One controller is accessed from one event.

    Lets take the other example of raising an event. The view raises the AddCustomer event which both the DatabaseController and AuditController are listening for. The DatabaseController takes the customer data and adds the customer to the database while the AuditController takes the customer data and stores the audit record to file. The two 'features' are more seperate in this approach and can be changed more easier.  The two controllers react to one event.


    There are no correct answers here. If you feel one approach is better for you in certain circumstances then use it. To be honest with you I'd be more inclined to use the events approach as it lends itself more to unknown future changes. I always like my classes to be independant.

    Hope that helps.
    www.dsmyth.net | www.dsmyth.net/wiki
    • Marked as answer by Lisa Tatum Monday, September 21, 2009 11:43 AM
    Monday, September 21, 2009 11:18 AM
  • well you know Derek I just found it really funny that even in a msdn article see above they use the presenter.Method(); ok who cares...

    If I must judge form case to case for my situation I prefer the KISS before more independence as I will definately not remove the AddCustomer method ;-)

    I plan my design and the whole layout of the classes etc... so I am settled with AddCustomer, DeleteCustomer etc.. so I will throw away the overhead of delegates thank you for your advice Derek and Eyal too.
    Monday, September 21, 2009 11:27 AM
  • I didn't decline your your approach, I already told you, you can do that using a delegate as a method parameter.

    But imagine you have to expand the UI, and this requires you to make changes to some of the method signatures of your presenter, the view that lies on that presenter will stop to function, unless you're doing overloading that complicate things even more, as you will have to change the calls you made in the view, and I didn't even mention unit tests it can break.

    The main problem in your approach and the real question is not about what events can do that your approach cannot do, and it's related more to design and concept, you're doing direct method calls on the view, where you tightly couple the view and the presenter, you may want to read about the observer pattern to fully understand it. 

    You should also understand that in design there are no hard and fast rules, if you don't need any delegation to be made, then it's safe not to, as long as it's not something that may change over time.


    Eyal, Regards.

    blog.eyalsh.net
    Monday, September 21, 2009 11:51 AM
    Moderator
  • I must still add something here: You said:"If the view calls 'presenter.AddCustomer()' then the view knows about the presenter and..."

    well the view knows anyway about the presenter as the presenter is instantiated in the view`s constructor... there is just no method called with the delegate version of mvp.

    Shouldn`t it be that way the view and presenter are instantiated in the programm.cs class? Where the View classes are created at first, then the presenter classes created and passed to the Views ?

    sample:

    programm.cs Main method:

    var customerView = new CustomerView();

    var customerPresenter = new CustomerPresenter(customerView);

    customerView is of type ICustomerView

    so the View is totally independend and can be exchanged without having to put the presenter = new CustomerPresenter(this) in the Views constructor
    Monday, September 21, 2009 11:55 AM
  • Hi,

    Done a bit of reading and I think in the MVP pattern then the view does indeed call the presenter as you have described.

    http://en.wikipedia.org/wiki/Model_View_Presenter

    The MVP is the wild child of another pattern called the MVC where the view raises an event to the controller and the controller then updates each of its associated views.

    http://en.wikipedia.org/wiki/Model-view-controller

    Perhaps the two here are getting mixed up... Eyal and myself thinking of MVC and your using MVP.

    If this is right then I do prefer the MVC over the MVP for all the reasons I gave before but perhaps the MVP is an easier pattern to implement and I think, based on the article, your doing correctly. This might explain why your code doesn't tie with MS, your MVP, MS code is MVC.

    With MVC you don't need to pass views into the controller but you can just create the views needed in the constructor, like a Wizard. The steps of the wizard are known and the controller just co-ordinates which view is shown when. However your code above would work just as well... even this would work to support more than one view of the same model.

    var customerPresenter = new CustomerPresenter();
    customerPresenter.AddView(new CustomerView());

    This allows the controller to co-ordinate the same information displayed on different views (with a call to RefreshViews()).

    void RefreshViews()
         foreach ICustomerView view in views
              view.Display(customer)


    Your doing the right thing according to the wikipedia article above.
    www.dsmyth.net | www.dsmyth.net/wiki
    Monday, September 21, 2009 1:42 PM
  • You may find this useful. Model View Presenter (MVP) VS Model View Controller (MVC), as I did just now, I mixed it up with MVC haha ... :)


    Eyal, Regards.

    blog.eyalsh.net
    Monday, September 21, 2009 2:11 PM
    Moderator
  • haha this guy is great and his statement too:

    I don’t find that type of "coupling" is bringing any problems so I deliberately applied “view make direct calls the presenter” and moved away from Fowler original implementation “view publish event which presenter subscribes for” as to complex to be used in real world applications

    source check also the comments from malovicn the articles author --> http://blog.vuscode.com/malovicn/archive/2006/10/10/Model-View-Presenter-_2800_MVP_2900_-pattern.aspx

    The MVP I do is the very fine so ;-)


    Monday, September 21, 2009 6:15 PM
  • @Lisa Tatum, Hahaha... funny and sad. ^^
    Eyal, Regards.

    blog.eyalsh.net
    Tuesday, September 22, 2009 8:59 AM
    Moderator