The problem is that the MVC pattern was designed in a system that doesn't really exist anymore. It was invented in Smalltalk at a time when UI libraries did not exist. To make a window dialog you drew all the boxes, highlighted the appropriate squares, made sure that the text you were drawing ended up in the right spot...etc...
Imagine what it would be like to write a dialog app using nothing but one large canvas. That's the world the MVC comes from.
A "view" in this system was a text box and it was a class that was responsible for drawing the box, the text, drawing selected areas, responding to changes in the text, etc...
A "controller" was another class that took mouse events that occured within this box like mouse moving, key down, key up, clicks, etc...and it would decide what happened. Should we change the text? Should we change the selection? Stuff like that.
A "model" was yet another class that represented the basic data and state of the component. A text box model would have the text of course, the font, selection, etc...
As you can see, in a situation like this the three components are very entangled in the representation of a single idea. It makes sense in this context to speak of a "triad".
Today, if you're working on creating a UI library and using raw drawing commands you might do something similar. But the application of the "MVC" pattern has spread beyond its initial purpose. Now days you have a "view" that may actually be a complete dialog, and a controller that's responding to events like "textChanged" or "buttonClicked". The model in today's MVC is normally something fairly disconnected from the system (but generally linked to the view by providing an observer interface of some sort) and there may be many views associated with the one model.
In a system I recently architected for example we had around 10+ views all observing a single document "holder" and its active document. A main drawing interface interacted with the layout of the document, various property views that observed the selected item and provided a record interface, and a smaller scale representation of the main view that showed the entire document instead of just the visible window. Some of these views had controllers of varying complexity that turned GUI events into changes to the document, which would in turn notify its various views.
Can you still call such a relationship a "triad"? Perhaps, but I think it implies too much of the former, older application of MVC.
Could you share controllers with different views? Depends on how similar the views are. I've found that generally speaking this type of object has behavior to specific to the view it's controlling AND the model it is manipulating to be very reusable...but there's always exceptions.
The model is not limited to interaction with the database, the model is responsible for getting and manipulating data.
So, to your view and controller, it should make no difference, if the data comes from a database or from a webservice or is even totally random, therefore you should do it in model.
MVC is a presentation pattern, that only separates the different representation layers.
It does not mean, that model has to be a uniform mess of spaghetti code. Your model itself can be layered as well, but the controller should not know, where the data comes from.
A public method in your model can be structured like this (Pseudo-code), which can be called by your controller:
public MyDataClass getData(int id) {
WebServiceData wsData = WebService->getData(id);
DatabaseData dbData = ORM->getData(id);
return new MyDataClass(wsData, dbData);
}
WebService
and ORM
may need to be instances of interfaces that can be replaced by mocks via dependency injection, but your controllers and views do not have to change for testing purposes.
Best Answer
This is a controversial topic in MVC/MVVM. Some say it is OK for the View to access the Models directly, other say you should wrap the Models in ViewModels in order to abstract them away from the View. I'm personally not a fan of either approach.
The one of the primary goals of MVC/MVVM is to decouple the UI, business logic and data. So with that concept in mind, allowing the View to directly access the Models creates a dependency that you might not want to have. On the other hand, wrapping the Models in ViewModels is often tedious and not very useful as the ViewModels tend to act simply as a pass-through to the Models.
I like the approach of having your Models implement a particular interface, lets call it IModel. Your ViewModel class can then offer instances of objects that implement IModel for View consumption. The View simply knows it works with IModel objects that it gets from the ViewModel. This removes the extraneous ViewModel wrapper code as well as hides the concrete implementation of IModel from the View. You can later swap out one implementation of IModel for another without affecting the View one bit.