tags:

views:

188

answers:

5

I've seen a number of examples of ways MVC components fit together on the web.


The Controller retrives data from the Model and passes it to the View

This seems a bit verbose and messy.

$model = new Model;
$view = new View;
$view->set('foo', $model->getFoo());
$view->display();

The Controller passes the Model to the View

What if the View needs data from multiple Models?

$model = new Model;
$view = new View($model);
$view->display(); //View takes what is needed from the Model

The Controller passes the View to the Model

$view = new View;
$model = new Model($view);
$view->display(); //Model has told the View what is needed


Which of these is the "best" way to go about things? If none, what is?

+8  A: 

The Controller retrives data from the Model and passes it to the View

As you said it's verbose and messy. But that's the most appropriate solution with the philosophy of MVC.

The Controller passes the Model to the View

Seems valid too. However it'll require for the view to ask for some model method. Which is not really in the spirit of MVC. Your view should only render the datas that are provided to it, without caring about the context.

The Controller passes the View to the Model

Forget that one. Here it is messy.

Damien MATHIEU
A: 

IMHO, option 2 (the Controller passes the model to the view) best maintains the proper decoupling and separation of concerns. If the view needs multiple models, the model passed in should be a composite data type that contains each model needed by the view. "Each model needed by the view" is usually different from your entity model in that it is flattened and streamlined for display, often called a ViewModel.

Option 1 (the Controller retrives data from the Model and passes it to the View) is quite similar to option 2, but I contend option 2 is preferable because it places less logic in the controller. In MVC, as much logic as possible should be in the model, leaving your controllers and views as simple as possible.

flipdoubt
"option 2 (the Controller passes the model to the view) best maintains the proper decoupling". In this case the view has direct knowledge of the model API and is kind of the opposite of "decoupling". Think of a view should not care what the underlying model is. It only job is to get data to and from the controller. The controller filters the data (both to and from) the view based on what is available from one (or more) models, and the business rules for the given application.
ChronoFish
"..In MVC, as much logic as possible should be in the model, leaving your controllers and views as simple as possible...." Maybe the difference in our opinion boils down to this: Business logic to maintain data should be kept in the model. Business logic of the application should be kept in the controller. We both use the term "business logic" to mean two (slightly) different things. I would ask you to consider the scenario where there are multiple models. The models should not know about each other (I would contend) and so there should be no "business logic" tying the two together.
ChronoFish
A: 

I tend to agree with the second one. MVC on the web can't really be implemented as it can in more stateful applications. Most web MVC implementations have you put your logic in your controllers and use the model for raw data access. I think the more correct way is to put your logic in your model. There is almost an implied 4th layer in that raw data access is done within the model, however the model is also responsible for giving that data meaning and updating the view.

The wikipedia article explains it pretty good.

Chris Gutierrez
On the last clause of your first paragraph, "the model is also responsible for giving that data meaning and updating the view", it sounds like you are advocating for option 3, where the model gets a reference to the view, if the model is to update the view. I am curious as to how the model would update the view. Seems like this might lead to code smells.
flipdoubt
That part is more regarding how non web implementations of mvc tend to work. A more specific example would be a typical cocoa application where key value binding is done from the view to the model. With the web, I tend to lean more towards option two where the controller acts to send the request to the model and a response from the model to the view. I feel like this closer mimics the more stateful implementations because the view gets an instance of the model and essentially handles updating itself.
Chris Gutierrez
I find WEB app to be perfect candidates for true MVC. UI can be HTML templates with 0 knowledge of the model or controller. Database backend ends can be accessed by a clean model that maybe a passthrough or hide more complex data integreity operations. The controller is the "page" you're hitting which merges the data (potentially multiple models) together with the (potentially multiple) views.Code Igniter in my opinion is a great MVC framework which spouts exactly this. - CF
ChronoFish
+1  A: 

The answer is self evident if you consider that the 'model' is the central artifact (potentially used across applications), and that a 'view' may (or may not) be aware of the specific model but it is (by definition) a 'view' of a (potentially abstract) model and again, potentially usable across applications. The 'controller' is managing interactions and is the most application specific element of the pattern, so it definitively needs to know about model and view details.

If the view is specific to a given model, you can use option 2. If the view is for an abstract model (and you can use it to display info from a set of models), you use option 1.

Option 3 is simply wrong.

+1  A: 

The answer to the original question is:

  1. The Controller retrives data from the Model and passes it to the View

MVC is actually very neat and clean. Remember what it is addressing:

  1. Code reuse (Models do not rely on controllers or views. Views do not rely on controllers or models. Controllers are app specific.)

  2. Separation of Logic (For instance changing an authentication backend from MySQL to LDAP require 0 change to a view. Changing a view's layout requires 0 change to model. Changing the database table structure requires 0 change to the controller or view).

Now IF you want your forms to be automatically generated from a table structure - the views are now tied to the table (tightly coupled). A change in the table require a change in the view (albeit potentially automatically). This may take less code - but the view is no longer dependable from a code-reuse stand point.

Similarly your views (in MVC) should be nothing more than templates. There should be no logic - just variables. All the "logic", aka business rules, reside in the controller. The models know how to get data and keep it normalized. The views know how to display data. The controller knows when to use the data and which views to apply the data to.

MVC is a strict 3-tier architecture. A two tiered architecture is valid for some applications. For quick mashups and "getting crap done" a one tied architecture can be appropriate (but you don't get style points).

Hope this helps.

ChronoFish