This is something that has been bugging me for a bit in a program I am trying to build. It is a desktop GUI application, and I settled on the use of the famous "MVC" (Model-View-Controller) architectural pattern for separating out the GUI and business logic. I've spent many hours wracking my head over various descriptions of this pattern that all seem to either not directly address the desktop use case, or contain a lot of jargon with regard I am not familiar, e.g. this:
https://stackoverflow.com/questions/5863870/how-should-a-model-be-structured-in-mvc/5864000#5864000
was perhaps one of the most interesting articles I found on the topic, but it took me many hours to penetrate because it was written for someone programming PHP in a Web context, which is not my chief area of programming experience. That said, I think I finally understand all the structure of the MVC pattern and could easily give a similar writeup with much less jargon.
However, the devil is in the details, and that's where I'm hung up right now. In particular, I am interested in the relationship between the View and Controller components - most questions on this seem to talk of the relation between the View/Controller and Model, but here it's this relation that's bugging me because as I understand it, Controller objects should not know about View objects and conversely, except in a very abstract sense which basically amounts to them passing messages or events between each other, particularly when seen in light of other design principles like SOLID (esp. the "I"). For example, a Controller object should not know there are things called "Views" out there, but it might know that there is a thing called a NewTweetsReceiver
. This tiny interface would, of course, be implemented by a View or perhaps several Views, c.f. Observer pattern.
All this is good so far - but now consider this. It is very common that we have in a desktop application the dynamic creation and destruction of GUI elements. For example (and this is actually where I am at!) when you hit the "New" command in a document editor, the next thing to happen may be that the editor throws a dialog box at the user asking for various initialization parameters for the new document to be created. The question is, though, where should we place the creation of that dialog box? What has the responsibility for that? Because I've heard statements like that "Controllers return Views" which suggests to me the following "back and forth" process:
- The user clicks on the "New" button in the application main window (which may be a view or several views in code).
- The view that has control over that "New" button tells a controller that the user wants to create a new document.
- The controller now produces as a response to that a view which is the dialog box (or could be, at least) asking for information.
- The user puts this information into the box and hits the "OK" button. In code, the view now informs the controller of the information entered.
But then it seems that when you do that, the neat walls of separate responsibilities start to erode, as we've effectively mixed together specifics of how the UI is laid out, namely, that it's apportioned between a main window and a dialog box, into the controllers, because the sequencing of events implied and even the creation of that dialog box are now baked into the controller logic. And that doesn't seem kosher: if we decide to change that organization, we have to invade the controller, which we shouldn't have to do so long as we're not adding new functionality, just reorganizing the UI.
So, how should we lay this out to properly preserve the V/C separation in the MVC pattern? The only alternative I can think of is having the main window part spawn the dialog directly, and the Controller only ever knows of a "create new document" as "create a document with such-and-such parameters", completely oblivious to however that stuff is gathered from the user. But if we take the dialog and window to be Views, then is it kosher to have views create each other? Yet I've never heard of that in any material I've found on this topic.
What am I missing here?