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?
1
@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.
4
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.
1
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.