Model View Controller/Presenter (MVC/P) & Humble Dialog Notes
The Origins Of MVC (Classic MVC)
References
- Thing-Model-View-Editor by Trygve Reenskaug. [Last accessed 10-Feb-2015]
- A Description of the MVC User Interface Paradigm in the SmallTalk-80 System. [Last accessed 09-Feb-2015]
- Twisting the Triad, the Evolution of the Dolphin SmallTalk MVP Application Framework. [Last accessed 09-Feb-2015]
Model View Controller (MVC)
MVC seems to have been conceived of in the world of SmallTalk. Reading about it from this historical perspective did clear a few things up for me. I ended up reading the following articles, which appear to be written by folks who were intimately involved in coming up with these patterns. Apparently Trygve Reenskaug was the originator (according to Pattern Oriented Software Architecture For Dummies) but it was first widely seen by people in SmallTalk.
The general strategy of MVC is to split up the responsibility for storing the data (the model), displaying the data (the view), and managing the user interaction between the two (the controller) into separate modules. A programmer can then modify one component without needing to know everything, or indeed (almost) anything about the other components.
For example, if the view for a text box is jazzed up, the view designer doing the fancy graphics stuff doesn't need to know how the text is stored or how the user enters the text. S/he just needs to know that s/he magically receives a message with information about what text to display and with this should display the text however desired.
Or as another example, a view on an address book retrieves a list of all names beginning with 'L' through the model. The model stores the addresses in a raw binary file. Now the software is to be upgraded to store the address book in XML. Because the view is separate from the model the storage can easily be changed without having to touch a single line of code in the view.
In summary then, we have 3 components:
- Model: The components of the system that "...simulate the application domain...". For example, a counter would store its value as an integer. The model is the combination of the integer itself, the rules that specify what values it may take, and the interface through which it is modified. These make up the "application domain" - the idea of a real-world counter.
- View: How the model is displayed. So for a counter in a GUI it might display a box and a set of up/down arrows and the current value of the counter, which it reads from the model
- Controller: The interface between the model, view and input device.
The diagram above, from the second reference, shows roughly how the interactions would take place. A user does something like hitting a key. The controller interprets the key press. Is it the enter key? Is it a normal character? I.e., the controller has knowledge about what the key does/signifies and starts a set of events.
If the key was a character, for example, the controller could message the model and ask it to append the new character to its character store. The model would do this and then signal, either using a publish/subscribe or other mechanism, to the world in general that it had made such an update. The view could then listen for and receive this update and query the model for the new text and display it however it wanted.
On the press of the return key, on the other hand, the controller might not ask the model to update its string store. It might instead signal the view to do something special, or signal another controller that the user has finished entering data.
The split of responsibilities is easy enough to understand, but it was the description of the controller in "Twisting the Triad" that elucidated things for me. In my development so far the controller seemed to be wafer thin and wasn't really doing a lot other than forwarding messages between the view and model. In the SmallTalk world the controller would do things like detect the key press, or detect the mouse click and figure out if the key press would modify the model or whether the mouse click was inside the view etc. Now, however, in modern OS architectures, most of this controller functionality already exists so the controller starts to become rather thin. As Andrew Bower et al say, "...the idea of a controller did not fit neatly ... most modern graphical operating systems, provide a set of native widgets ... [which] already include most of the controller functionality embodied as part of the underlying operating system control...". I.e., the controller wasn't applicable to modern systems as there is no need to listen for key presses, mouse clicks etc: the OS does this for us.
Model View Presenter (MVP)
It was for this reason that Twisting The Triad came up with MVP (Model View Presenter).
TODO: Finish description...
http://aviadezra.blogspot.com/2007/07/twisting-mvp-triad-say-hello-to-mvpc.html https://martinfowler.com/eaaDev/uiArchs.html
See also Martin Fowler's Seperated Presentation:
This pattern is a form of layering, where we keep presentation code and domain code in separate layers with the domain code unaware of presentation code ... The presentation is able to call the domain but not vice-versa ... Although the domain cannot call the presentation it's often necessary for the domain to notify the presentation if any changes occur. Observer is the usual solution to this problem ...
MVC As Described By The "Gang Of Four"
Humble Dialog
The idea of the Humble Dialog is to have a passive view where operations on the view are reduced, as far as possible, to simple get and set operations. This has two benefits:
- Business logic remains encapsulated and is not mixed in with the view code. This itself has a couple of benefits:
- The business logic is more easily identifiable and understandable as the read does not have to bother with the intricacies of a GUI,
- The business logic is more maintainable and testable as a result,
- Because the view code is separated, the view can be updated independently of the model and different views can be created and used in different circumstances without duplicating business logic. The logic of the view is more easily testable because the passive view can be stubbed, and because the view was passive it was wafer thin anyway, reducing the amount of hard-to-test code.
See the original article by Michael Feathers.