1

Alright so it is an essential part of OOP that one class should only do one thing, and it makes sense. In practice I've seen that classes which don't obey this rule get thick and cluttered.

So I was thinking and I kinda can't wrap my head around how the controller fits into this. If each method of a controller should represent a different page from the website, then this doesn't really make much sense to me. Yes the pages may be related, such as /user/edit and /user/view which are in the same controller, but if I'm going to display one of those pages, loading the other method and possibly many more is completely pointless.

It's probably that I'm missing something since people have been using this approach in major frameworks, but can you help me figure out what?

  • 2
    Putting User related actions into a single controller object is basically for convenience. Makes it a bit easier to verify the various methods stay in sync with each other. Nothing in MVC prevents you from make a controller per action i.e. UserEditController, UserViewController etc. I do this quite often as it allows sharing common edit code among multiple controllers. – Cerad Feb 1 '15 at 17:26
3

@DavinTyon's answer was very good, but I think that there are a couple other things worth mentioning. For better or for worse, the router/controller part of MVC is functional. The hierarchy works like this:

  • The router takes the URL and figures out which function it should call
  • The controller acts as a module to encapsulate related functions
  • The action is the specific function that gets called

This fits well with mapping functionality to URI space. One thing that search engines have taught us is that URIs matter. They affect our page ranking, and they are contracts to consumers (users or machines) that you can get a resource at this location.

The specific action is a set of instructions on how to prepare the resource for the request. Mixing functional and object oriented approaches feels disjointed and difficult to wrap your head around in many cases. Unfortunately, as we build more and more distributed systems, the influence of functional programming will only get greater.

MVC attempts to help bridge that divide:

  • Controllers are modules of related actions (functions)
  • Actions prepare resources for the view templates
  • Models are object oriented and are where you apply all your object oriented principles.

I think this is a better way of wrapping our head around an MVC application, and also helps us find the right patterns and design principles for the various pieces.

One of the main drivers behind MVC was also improving test-ability. You can run the actions on a controller without a web server or full infrastructure available. You can also test the contents of the Model and ViewBag that were passed into the View object returnd from an action. The model remains as testable as you designed it. The last piece of making sure the view looks right remains a manual process, but the riskiest portions of the app can be fully tested.

  • So basically then I don't actually need my controllers to be objects at all? I can immediately come up with an idea that every action can be a separate file and I can build a system into the router that will be able to find all those files ( which is now in fact almost the same except it finds controller methods instead of files ). Would this still be correct from the MVC point of view? – php_nub_qq Feb 1 '15 at 14:04
  • I'm not quite sure if it is clear what my problem with my current approach is though. What I find troubling is that for example my User controller has 16 methods and most of them are 20+ lines. No matter how little of significance that is, I still find it a waste to load a file and use 10% of it, rougly. – php_nub_qq Feb 1 '15 at 14:07
  • @php_nub_qq: If you find that a wast, you should not even try to think about the waste you incur when you open an application like MS Word to write a letter. Or how much of the PHP engine your code leaves unused but loaded in memory :-) – Bart van Ingen Schenau Feb 1 '15 at 16:28
  • A compiled language (all .Net languages are compiled) doesn't really load a class file each time it is used. It loads the assembly once, and instantiates the controller as needed. Since just about everything is just instructions, a controller doesn't really take up much memory at all. It's more efficient than you are imagining. However, with your first comment it would still be correct from an MVC point of view. It can be a lot of work, but it behaves similarly to what you get now. – Berin Loritsch Feb 1 '15 at 22:30
1

I think you are referring to the Single Responsibility Principle (SRP). Which, in summary states:

that every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class

However, this does not mean that one class should only do a single thing. In means that a class or module should only have one reason to change:

Robert C. Martin defines a responsibility as a reason to change, and concludes that a class or module should have one, and only one, reason to change.

So, in your example of /user/edit and /user/view, the controller is responsible for exposing user to something beyond the boundary of the application, like a view.

The higher in the stack you get (or the more you aggregate for viewing), the more you implicitly depend on. MVC pattern is a way to minimize this. By separating responsibilities when preparing data for viewing. MVC can further be split into vertical slices in your application (user for example). This moving the design of the application more and more towards SRP. This is kind of the best that we have at the moment. There are other patterns (like MVP, and MVVM) and maybe one day a better one will emerge and be adopted.

SRP is a principle, which means we should consider and strive towards it when designing applications. But we also have to be pragmatic and get things done. So, there is a trade off.

  • MVC also allows you to test the controller without having to go through the transform process. Ensuring the response is a 404 when a resource doesn't exist, etc. is a lot easier when you don't have to fire up a web server and work through the web client APIs. – Berin Loritsch Feb 1 '15 at 13:43
0

IMHO, Model-View-Controller (MVC) design pattern purpose is to separating your application concern into Data (model), Presentation (view) and Business logic (controller) to increase the reusability and maintainability of your code[1][2]. In MVC design pattern, the controller component contains every method in your application which have the same domain. Lets say, you will put every method that related to user into UserController (login, register, add, delete, etc) so with SalesController which will contains every method related to sales.

So, i think its more clearer and cleaner to grouping your method which has same domain into the one controller instead of creating controller for every method :). Although i never test the performance (ex: class loading in your case) but i believe php and web server will handle it for you in the background.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.