MVC concept is to make a clear division between domain objects (model) and presentation objects (view and controller); it introduces the Observer-Synchronization mechanism to support multiple presentations (observers) of single domain object (observable) and to keep the domain objects completely unaware of their presentation objects.
Even though MVC had constantly improved over the last three decades - its concept remained unchanged.
View is a widget on the screen surface, it can be a button, label etc. Its purpose is to display model data (usually one of its fields). It communicates directly with the model.
Bear in mind that we are talking about widgets of the 80's that are only about the display, they doesn't know if they are being clicked by the mouse or pressed by the keyboard.
Controller is a logical entity that always has view (widget) as a pair. It process user inputs coming from input devices such as keyboard and mouse and command the model as appropriate. It communicates directly with the model.
Model is a bunch of business objects that represent the problem domain. Mainly, those objects stores data, interact with DB and services and handle business logic. It's completely ignorant of the UI, thus it doesn't know nothing about neither view nor controller.
CollaborationThe diagram bellow shows how MVC objects collaborate. The objects in the diagram represent the most simple UI that has two widgets (represented by the widget-controller pairs) and one business object (represented by the model).
The controller receives inputs from the user, if the input is relevant to its widget(view) pair - it command the model as appropriate, the model performs some business operation, changes its state and raise the proper event, the widget(view) respond to that event, ask relevant data from the model and changes its display.
What you can't see in the picture above is that view has link to method in the model so it can retrieve data whenever the data changes, also, you can't see that controller and view are allowed to link each other directly.
InteractionThe 'Speaker Control' GUI that is shown bellow has one simple use-case. [Trigger:] The user click on the 'Increase Volume' button [Main Success Scenario:] the speaker volume is increased by one and the text-box display is updated with the current volume .
MVC design for this GUI will have widget-controller pair for each visual element (button, textBox, label) and one model object to set the speaker volume and to hold the current volume.
The diagram bellow shows how MVC objects interact.
Application Model MVC
As Smalltalk evolved new entity called 'Application Model' (AM) was added in order to shield the model and the view from presentation logic responsibilities. AM acts as intermediate class between the model and the presentation objects (view and controller), thus, controller and view don't access the model directly and don't register to model events, instead, they access the AM and register to AM events.
CollaborationThe controller receives inputs from the user, if the input is relevant to its widget(view) pair - it command the AM as appropriate, AM perform some UI related operation, changes internal UI related state, and command the model to change, the model performs some business operation, changes its state and raise the proper event, AM respond to that event and raise the same event, the widget(view) respond to AM event, ask relevant data from the AM and changes its display.
Why the change?We have seen that classic MVC works great with the 'Speaker Control' GUI - the problem is that real life UI will probably have use-cases that are a little more complex.
To illustrate this point, let's add another rule to 'Speaker Control' use-case: If the volume exceed 12 than the color of the text-box text should change to red. The question is - who should be responsible for this piece of presentation logic?
We can force it on the model, so it will compare the volume to 12 and raise some special event - but that will be awkward. We can extend the text-box widget, so it will compare the volume to 12 and change its own color - that sound better but still we'll rather keep the widgets generic and ignorant of any kind of logic.
Exactly for this kind of situations the AM was invented.
The diagram bellow shows how AM handles the new role.
User click on the 'IncreaseVolume' button, controller command the AM to increase volume, AM delegate the command to the model, model command the speaker and raise 'DataChanged' event, AM respond and delegate the event to the widget, widget ask AM for current volume, AM ask it from the model and return the value to the widget, widget then update its display.
Now, AM start dealing with the presentation logic: AM ask for current volume from the model, it checks if the current value is bigger than 12, if it is - it raise ColorChanged event, the widget respond to that event and update it color.
Another benefit of using the AM is that it can store view related data such as the current color of the widget, which item in the list is currently selected, witch widget is currently disable etc.
What's the problem?The problem with AM is that it's not allowed to manipulate its view directly, it cannot simply change the color of the text-box, it must raise the 'ColorChanged' even and have the widget respond to it.
Read 'Twisting the MVC Triad and find out how MVP design pattern solve this problem.