Um, Here is a diagram of MVC dependencies:I want to avoid passing the model itself to the view completely to keep them ignorant and separate.
Note that these are packages (groups of classes), not classes.Code:+--+ +--+---------+ | Controller | +------------+ / \ / \ / \ / \ +--+ \/ +--+ \/ +--+---------+ +--+---------+ | Model | <----- | View | +------------+ +------------+
MVC applies the Dependency Inversion Principle. The controller is a high level package and thus may freely call the other two packages. The controller is dependent on the other two classes. The Model is a low level package and thus may not have dependencies on the other two packages. The View is dependent upon the model, but not the controller. (See Principles of Object Oriented Design for a list of types of dependencies.
If you need to communicate "against the grain" then you would use the Hollywood Principle to allow communications without creating dependencies.
For example, the model could communicate to the view that data has changed and that the view needs to be refereshed. To do this, it would issue a data changed event which the view would listen to. Since the model has no idea what kinds of objects are listening to its events, the pattern of dependencies is preserved, even though there is communication to the view originating in the model. It might be the controllers responsibility (being at the highest level) to pick the correct view to register to listen to the model.
Traditionally, the controller is responsible for managing input. (In a PHP web app, this means that the controller classes would be the only ones with access to the $_GET, $_POST, etc arrays.
So, input goes in the controller package, output goes in the view package, and business logic goes in the model package.
The controller also acts as a mediator between the other two classes. Sometimes, you might want to split the controller up. You might also want to split up the model to encapsulate database access into its own package.
The advantage is flexibility: if you need to output in a different format (say XML instead of HTML), swap in a different view. If you need to support application scripting, swap in a different input controller. If you need to support a different database, swap in a different database package.Code:+--+ +--+---------+ | Controller | | (input) | +------------+ /\ | +--+ | +--+---------+ | Controller | | (mediator) | +------------+ / \ / \ / \ / \ +--+ \/ +--+ \/ +--+---------+ +--+---------+ | Model | <----- | View | +------------+ +------------+ | | +--+ \/ +--+---------+ | Database | +------------+
The model, as the holder of the application (business) logic cannot be swapped out. You cannot swap out a Web Store model for a Web Log model in an application. You could swap out a MySQL implementation of a Web Store model for an Oracle implementation of a Web Store model. People develop persistence layers to avoid having to make any model swap at all when they want to make this kind of implementation change.
Note that being at highest level, the mediating controller will probably have to change no matter what types of changes you make to your application.