4

I'm playing with MVC in PHP. I'm not using a framework, I'm just trying to understand the pattern.

Sometimes I see controllers, for instance in this tutorial, that are instantiated with Models and Views passed into the constructor, and in the same tutorial the view ( here 'Template' ) class, takes a Controller in the constructor!

So my question is:

  1. Why might the view need a reference to its controller? Shouldn't the view be the passive partner in this relationship?
  2. Should a controller ever have an internal reference to a particular model? Or to put it another way, why not just instantiate models in controller actions and use them that way?
djb
  • 5,591
  • 5
  • 41
  • 47
  • 1
    BTW, that tutorial is just horrible. It used global variables, error suppression and ancient `mysql_*` functions. – tereško Jun 14 '12 at 10:56

5 Answers5

9

Given the many variations and misconceptions of MVC on the web, I voted to close the question as Not Constructive. I provide this answer as a Community Wiki, because of the limited comment size.

enter image description here

MVC was originally conceived by Trygve Reenskaug for Desktop Environments and not for the web. What we see nowadays are mostly variations of the original pattern in some form, like MVP, HMVC, Model2-MVC and so on. Their implementations differ from each other and people spent lots of time quibbling over what "MVC" really is or how it should be implemented.

enter image description here

Personally, I prefer the Patterns of Enterprise Application Architecture definition of MVC which says MVC splits user interface interaction into three distinct roles, because this definition has no notion of implementation.

In the book, Fowler notes that the most important distinction is the separation of the Model from the Controller and View. While the book does cover the associations between the roles to get that argument across, I think the main point is to understand and focus on the roles and not the implementation.

Design Patterns are blueprints, not detailed schematics. Also, MVC is a Pattern Language. It's aim is to add structure/form to a project. Understand what the roles are for and then come up with an implementation that works in your project.

enter image description here

Fowler also has a lengthy article on GUI architectures covering MVC explaining the associations and dependencies in details, in case you don't have the book handy.

Images/Slides from: Architecture the Lost Years (Robert Cecil Martin; 4 Nov 2011)

hakre
  • 193,403
  • 52
  • 435
  • 836
Gordon
  • 312,688
  • 75
  • 539
  • 559
3
  1. If you have user inputs, you need to know where to send them.. to what controller.

  2. I don't like having my controllers play with models directly, because controllers are exposed to the "outside world", and prone to attacks. You can have a look at service layer pattern, Data Transfer Object pattern, etc. I like to have my models isolated behind a service API that controllers will use. If you need a good book about patterns, you can look for Martin Fowler's :)

PEM
  • 1,948
  • 14
  • 13
  • Thanks. In your 2), doesn't the service API effectively become the model, to all intents and purposes? – djb Jun 14 '12 at 09:22
  • not really in fact. The service APi is here for the controller to do basically crud actions. for example, you call the controller and ask for an index action listing all customers. you hit customer controller. this controller then will call a getAll on the customerService. The service might call a dbMapper that will connect to the db, retrieve all customers, create instances, populate them and return them to the service. The service might then call a DTOmapper to transform instances into DTOs and return them to the controller which will return an array of dto in a json form to the view... – PEM Jun 14 '12 at 09:45
  • There are no multiple "models". Model is a layer. – tereško Jul 06 '12 at 13:58
  • Yeah, some people love playing with words huh? Entities would be suiting you better? – PEM Jul 06 '12 at 14:08
1
  1. The view shouldnt reference a controller (other than the action links of course). The controller performs the action it is told and sends the result to the view.

  2. As far as I have used MVC, i instantiate the model in the action and use it that way. I dont like having my controllers bound to models. Normally i use a repository structure to access my models. In larger projects i have a service layer between the controllers and the models. In .net MVC I have started playing with the use of viewmodels as an entity the controllers and MVC part of the app looks at, while my services handle anything to do with my domain models and returns the viewmodels.

ruffen
  • 1,695
  • 2
  • 25
  • 51
  • Thanks. What do you make of what @PEM says about 1? – djb Jun 14 '12 at 09:20
  • 1 i dont agree, if he means you should have a reference from the view to the controller in the code. I.E. have a reference between classes. Knowing what url your on is enough, I think. 2 i agree, if he is referring to some sort of domain model. What is required by a Domain model might be different from a "view" model. Separating app logic into services also keeps the controllers from being cluttered. Having the services also allows you to expose application logic to other applications as well. – ruffen Jun 14 '12 at 09:50
1

Since i already managed to extensively write about model in context of MVC and PHP, lets just focus View and Controller parts of the triad.

As @Gordon already mentioned that, what we do in the Web, is not classical MVC. It's not rally possible. Instead we have come up with distinct variations on original idea.

View is not a template

Unless you are using a particularly bad implementation of MVP, the view instances are objects, responsible for presentation logic.

Whether controller instance needs access to view depends on which MVC-inspired pattern you use. In MVP and MVVM patterns controller instance requests information from model layer and passes it to view (either with some modification or additional flags).

In the Model2 pattern (which is somewhat closer to original concept), the view instance itself is able to pull information from model layer. In this case there is no need for controller instance to have access to it.

What is controller responsible for ?

Instances of controller should not be directly instantiating structures from model layer. There are two main reasons for it:

  • causes tight coupling to particular class names, makes for harder testing and maintenance
  • adds additional responsibility (or reason-to-change) and thus - violates SRP

Initialization of structures from model layer is complicated. They usually require you to inject database connection, cache handlers or even other structures from model layer. This task should be left to a separate factory-like instance (shared between controller and view instances), which controller uses.

The main responsibility of controller instance should be changing the state of model layer. It should take input from user, and translate it in the form, that is understandable to model layer.

Keep in mind, that model layer as a whole must be completely ignorant about view and controller instances.

Community
  • 1
  • 1
tereško
  • 58,060
  • 25
  • 98
  • 150
1

In my experience, there are many interpretations of what exactly MVC means. Almost everyone agrees that generally:

  • Models implement business logic, and encapsulate data access.
  • Views implement presentation logic.
  • Controllers handle input and control flow.

How they connect and talk to one another is a matter of debate, argument, fistfights, and holy wars.

In practice, controllers usually load views and models, views sometimes load models and controllers, but models don't generally load controllers or views.

Why would a view load a controller? Let's say you implemented a widget that has it's own controller, model and view. You want to load this widget on multiple pages on multiple places. Easiest way to do so is to load the widget's controller in a view.

Why would a view load a model? Maybe you wrote your controller so it can load two or more views, and you don't want to have to load a different model for each of the very different views. So you simply tell each view to load it's own models.

Separate the roles, but allow for whatever interaction most efficiently and logically implements the system you need.

Gustav Bertram
  • 14,591
  • 3
  • 40
  • 65
  • Great answer. By "loading" you mean "depend" right? Like a View may depend on a Controller (may have "has - a" relationship with Controller), a View can depend on a Controller.. – Koray Tugay May 12 '17 at 05:34
  • In this case, all I mean is that a specific method in a controller might load a view object, feed it some data, and then display it. That controller method "has - a" view in the loosest sense. In terms of object composition, it's much more an association than an aggregation or composition. – Gustav Bertram May 12 '17 at 06:44