MVC Design – Should a Model Contain Subview Models?

Architecturedesignhierarchymvcobject-oriented

Some background:

A colleague and myself have different interpretations of MVC which means, given the same problem, we are coming up with radically different solutions. He comes from a Java background where every component of MVC may traditionally model an object and I come from a Haskell background and have little or no experience with OOP.

The problem space:

The problem we are trying to model acts a little bit like a desktop environment. We have a notion of the users session (perhaps their login, their desktop background) and the processes on their desktop (say iTunes, Finder, etc) which each have their own model properties (minimised, etc).

We agree on the following point: we think HMVC is the best representation. We agree that we have two MVC objects, Session (desktop) and Process (application) and that we don't want a Process to have a notion of Session or a backlink.

Once place we disagree on however is the core meaning of MVC and how that affects where we keep the list of processes on the users desktop.

His interpretation:

He argues a very valid point which traditionally is easy to model in code and in our rendering system. He says that the list of processes should be a list of ProcessController objects within SessionController which in turn have their models as separate objects inside them. This means that there is a significant amount of state within both SessionController and SessionModel which is relevant to what SessionView needs to render.

This seems to be very much in harmony with what we were able to read on the internet in a brief search.

My interpretation:

My interpretation requires the largest architectural change and seems harder to implement in the code, but I believe it is more conceptually correct. I would like somebody to explain why this is not the case, or present a different model (if not MVC) that aligns with this interpretation and highlight some strengths and weaknesses for both patterns so we can make the most informed decision (neither of us have a strong background in software architecture).

I see MVC as a triad with three interchangeable components: the Model, the Controller and the View. This agrees with what I am able to read on the internet, and some sources will say things along the lines of like 'views, controllers and models with the same interface should be interchangeable to different effect'. The way I imagine this to work is as follows:

  • When you swap the model, you are changing the way data is validated or stored
  • When you swap the controller, you are changing how the page behaves, but not anything which could alter the conceptual data content of the page
  • When you swap the view, you are changing the way the page is displayed

From this, I reasoned that given any Model and View, swapping only the controller should not change the data the page initially renders because the controller should change only the behaviour and not the 'content' of the page. I think this aligns with the conceptual visualisation of the controller as a 'station controller' in a rail system, a plan of the rail road as the model and the actual physical manifestation and look/feel of the tracks (in different flavours, say 'Real' or 'Virtual 3D') as the view.

Here's where we disagree:

I argue that because the data that will be displayed to the user in the SessionView is changed by the different processes on the desktop (I model the processes as relevant data), the SessionModel should contain the list of instances of ProcessModel. This means that using any random SessionController with the same SessionView should conceptually show the same data (processes on the desktop).

He argues that it makes more sense for a Model to never know about another model. This means that the SessionController would have a list of ProcessControllers within it and each Controller object has a link to its model. Given a SessionView and the same SessionModel but a different SessionController the data displayed to the user should be radically different.

Please argue for/against each interpretation and help us to reach the most informed outcome.

Thanks for your time!

Best Answer

The key in understanding MVC lies in the separation of the responsibilities, as MVC is simply SRP applied to UI code. It separates what data has to be displayed, from how to display it, from how to handle screen events. But an important (and often missed) detail of the original definition of MVC is that it was designed for a far more granular level. For instance, you'd have ButtonModel, ButtonView and ButtonController objects, "just" to present a single button on a screen. Missing this detail is what causes so many different opinions on the subject. You can check the Java Swing architecture to see what I mean.

The point of MVC is to allow the code that serves each responsibility to be changed without affecting the code for the others. For instance, you would be able to switch the rendering of (a component on) the screen without having to touch the data representation nor the event-handling logic. So, to a degree, this goes along with what you say here:

From this, I reasoned that given any Model and View, swapping only the controller should not change the data the page initially renders because the controller should change only the behaviour and not the 'content' of the page. I think this aligns with the conceptual visualisation of the controller as a 'station controller' in a rail system, a plan of the rail road as the model and the actual physical manifestation and look/feel of the tracks (in different flavours, say 'Real' or 'Virtual 3D') as the view.

However, in your context, the level of granularity is off; you have a SessionView that seems to be responsible for a whole screen. At this level, the responsibilities get too coupled to fully separate as intended by MVC, thus it may not provide the full benefits.

Your problem is in separating the three UI responsibilities (rendering, the data and the event-handling) for both sessions and processes, a total of six. Because of the level of granularity of the components (whole screen), this becomes impossible, and causes the dissonance you find yourselves into.

You want to separate the rendering and event-handling responsibilities for both Sessions and Processes, but you'd couple their data. Your colleague wants to decouple the data, but couple the event-handling.

So in the end, this is an SRP problem. My way out would be to decrease the level of granularity down to a point where you can clearly separate Sessions from Processes. If you can't do that due to economics, you guys simply have to weight both sides of the trade-off, choose the least worst, and sign it off as technical debt. This is, after all, what design decisions are all about. :)

Related Topic