3

I am trying to implement MVP with Passive View for the first time, but I am a little confused as to who is notifying whom in this pattern. I understand that views notify the presenter if they get changed, and the presenter in turn notifies everyone else (other views and the model).

Now, in my case I have multiple views, and I also have a model that can get changed outside of the UI. The following two scenarios can happen:

  1. View[i] gets changed and notifies Presenter. Presenter needs to notify all other Views and Model, but not View[i]. Furthermore, neither Views nor Model may send out change notifications to Presenter even though they just got modified (otherwise there would be an infinite loop of events).

  2. Model gets changed and notifies Presenter. Presenter needs to notify all views, but not Model. But none of the Views may send out change notifications to Presenter even though it just got modified.

How will the presenter whom to notify and whom not? And how does the model know if it needs to send out change notifications? After all, it just got modified, but it doesn't necessarily know by whom.

One possibility is to let everyone (model, views and presenter) freely send out change notifications, but to store a reference to the object that originally triggered the change inside the notification (thereby encapsulating the notification in an event object). Every object then only sends out notifications if he is not the original trigger of the change. But is there a simpler, cleaner way of doing it?

dpk
  • 31
  • 2

1 Answers1

1

There are several ways to approach this, but the two I would recommend are the Mediator Pattern, or some type of Event Aggregator.

The idea behind the Mediator pattern is that it allows you to encapsulate how a collection of objects should interact in a specific scenario, while keeping them ignorant of each other.

Something like this:

public class MyPresenterOne{
   public event EventHandler OnFoo;
}

public class MyPresenterTwo{
   public void DoStuff(){
      //Something interesting
   }
}

public class MyMediator{
   public MyMediator(MyPresenterOne p1, MyPresenterTwo p2){
      p1.OnFoo += (o, e) => p2.DoStuff();
   }
}

An Event Aggregator is a loosely coupled Publish/Subscribe paradigm where you aren't really listening for events, but rather messages. One party registers interest in a type of message, but doesn't really care where it comes from.

public class MyPresenterOne{
   public MyPresenterOne(){
      EventAggregator.Publish("OnFoo");
   }
}

public class MyPresenterTwo{
   public MyPresenterTwo(){
      EventAggregator.Subscribe("OnFoo", () => {
         //Something interesting
      });
   }
}

The mediator is a bit easier to implement, and the intent is very clear, but it does need to have intimate knowledge of the various components involved. The idea is to keep a mediator focused to specific scenarios of composition instead of having one giant mediator.

The Pub/Sub paradigm is pretty elegant and works well to keep components loosely coupled, but requires a lot more thought in terms of what kind of messages to publish.

Josh
  • 44,706
  • 7
  • 102
  • 124