I was reading about code architecture and the MVC/MVVP paradigm. Ideally, we should have the model as a high-level policy/component where it should not know or directly depend on other components, such as the view. Essentially, one of the roles of the controller is to send inputs to the model and thus has the model component as a dependency. However, we need the model needs to communicate with controller whenever it's state changes. From my understanding, we shouldn't have the model depend on the controller as it would we would create a bidirectional dependency between the components, which can lead to unmaintainable code and difficulty adding changes. So, I imagine the bidirectional relationship to communicate as the following:

BidrectionalRelationship

However, if we create an interface for the model to communicate with the controller, IController, it can remove this bidirectional communication. IController implements all the methods that notify the controller changes. The dependency would look like the following:

Single Directional Relationship

Now, the model is ignorant of the actual implementations of the controller. Therefore, changes in the controller, should not affect the model components. I was wondering if adding an interface for the controller the best way for model and controller to communicate with each other.

I am also aware that in some programs, the model can directly communicate with the view directly using the observer design pattern. However, the model should not know the implementation details of the view since the model should be respected with high-level policy and should not know about low-level policies, such as the view. Therefore, in this case, let's not consider the observer pattern for the model to communicate the view.

  • 3
    Why are you eliminating the observer pattern from consideration? – Robert Harvey Oct 12 '17 at 2:49
  • Good question. The model should not know the implementation details of the view since the model should be respected with high-level policy and should not know about low-level policies, such as the view. Therefore, in this case, let's not consider the observer pattern for the model to communicate the view. – mtber75 Oct 12 '17 at 3:20
  • @mtber75: The observer pattern is not just for communicating changes from the Model to the View, but for any case where one component must send updates to an unspecified number of other components and/or without a direct dependency between the components. – Bart van Ingen Schenau Oct 12 '17 at 7:30
  • 1
    MVVP? what does it stand for? – Ewan Oct 12 '17 at 8:20
  • 1
    Note that you can raise an event on a Model (and have any controller subscribe to that event) without the model having any knowledge of the controller. – Robert Harvey Oct 12 '17 at 15:01
up vote 2 down vote accepted

The Model knowing about, or being dependent on the Controller or View is not normally a problem in MVC.

In MVC the controller and View depend on the Model. Thus the model has no need for any dependency on anything.

You can even go further and get rid of the View's dependency on the Model, by creating and populating it in the Controller. Which is standard for web applications.

These methods do give you a problem for the case where the Model updates outside of a Controller event. For example, lets say the model has a Time property which updates automatically to the system time every second.

In these cases you will wish to update the view without having a controller event. This can be achieved by a number of methods

  • Have the Controller or View raise a periodic event every second to update the view. eg a Timer object.
  • Have something check for or be triggered by the underlying cause of the Model change and call the controller. eg a database trigger.
  • Have the Model raise an Event when the event happens and have the Controller and/or view bind to this event. eg Model.OnTimeUpdate

Obviously the best solution is to avoid these types of uncaused changes in your Model. Usually there is a cause of the change, and you can route that cause through a controller, thus capturing the event and removing or exposing a dependency of your Model at the same time.

MVVM - Model View ViewModel takes this further by Binding the View to events raised by the ViewModel and vice versa. This may suggest extra Events be added to the Model in order to further leverage this pattern, but such events are by no means required, nor do they require any dependencies be added to the model.

  • 1
    I like your third bullet. I think there might be some misconceptions about the Event here; you can raise an event on a Model (and have any controller subscribe to that event) without the model having any knowledge of the controller. – Robert Harvey Oct 12 '17 at 14:59
  • You guys answered my question right on the spot :). Thanks. I've implemented in javascript of the model notifying the controller its changes. Basically, the model has a notifier callback/higher-order function where it's input is a state that has been changed within the model. This callback function is called whenever a state of the model is mutated. The controller knows the model and will set the callback function with one of its own functions. Consequently, whenever the state of the model changes, the controller will get notified and run one of its methods. – mtber75 Oct 13 '17 at 18:55

NotifyControllerChanges() should be an event, to which any controller in your system can subscribe. It would be part of the public API of your model, not an implementation detail. The model does not know (and does not care) who subscribes to it, and therefore has no knowledge of the subscriber.

If this still bothers you, then consider that the other methods on the model that you call from the controller must still know where to return to, yet we still treat them as having "no knowledge of the controller."

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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