Welcome Guest, Not a member yet? Register   Sign In
Fat controllers vs many small controllers
#1

[eluser]jleequeen[/eluser]
Hello Everyone,

I've been converting an old legacy app at my job into CI for the last few weeks and have run into some issues when trying to break up the app into controllers. The views are easy, but when grouping them together into your controllers is where it gives me fits. I've approached the system from two points of view. One, from a user and roles perspective and the other from strictly a controller/action but still have trouble deciding. I was wondering if anyone out there could give there two cents on how they decide what becomes a controller, and how do they handle the breakdown between different user roles.

I'm in the mindset that if your application needs to generate reports, then you would create a reports controller, and then add each method for each report you want generated. And only give access to the certain reports between users/roles. But over time it seems that the controller would get "fat" as you keep adding new actions. Just curious as to whether it would be better to have the reports controller, or would each report need it's own controller to keep them small?

Thanks in advance for any comments.
#2

[eluser]Eric Cope[/eluser]
I am not sure if this answers your question, but I would break the work logically based on scale. One reports controller could have several functions that call common library functions and then proceed to call different views. This allows rapid development and scalability as well as easy refactoring later if you decide you need to optimize some function. You have to decide whats important to each project. If the fact controller can be logically divided, then there should be no issues in splitting it. Place common logic in a library (this will enable easier refactoring later) and call library elements. Does that provide the type of insight you were looking for?
#3

[eluser]Colin Williams[/eluser]
For a controller that handles requests for reports, I could see a view() or generate() method the serves up all reports, regardless of what type (use additional URI params to indicate this). I could also see add(), edit() and delete() methods (if indeed this particular app stored reports in a DB... just assuming)
#4

[eluser]Developer13[/eluser]
From the father of PHP himself (Rasmus Lerdorf):

"A web application by its very nature is a series of small discrete requests. If you send all of your requests through a single controller on a single machine you have just defeated this very important architecture."
#5

[eluser]jleequeen[/eluser]
@Eric Cope

I understand what you are saying, just having trouble putting it into practice consistently.

@Developer13

I've read that statement from Rasmus before. I'm actually all in favor of keeping controllers smaller. But at what point does that happen that kind of makes me think about things. For instance, I might have a user controller that handles things like add, edit, delete users. It seems to me that these actions logically fit inside of a user controller. But when it comes to say, logging in a user, does that go into user/login...or does that need to be a login controller all it's own. I also understand that you could get into a situation where you start relying on your user roles to determine the functionality and I'm not so sure that is the best approach, because in the end, you could end up with one big user controller that does every action, if that makes sense.
#6

[eluser]Colin Williams[/eluser]
[[ REMOVED ]]

Thought I was in a different thread... :roll:
#7

[eluser]sikkle[/eluser]
We have to be serious there, rasmus himself build some stuff within 4-5 function in int.

I can think as 300-400 line per controller could be good base for speed, i mean i use it that way and that scale pretty well's i'm happy with timeload too.

Hope that help.

good luck.
#8

[eluser]Michael;[/eluser]
Greetings jleequeen,

I come from a procedural background in coding, beginning all the way back in COBOL 74 and RPG II. My first introduction into functions was C ( yes, just "C", not "+", no "#", just "C"; I am *NOT* old. Tongue ). When I learned how to use functions ( and thus libraries, includes, etc I just went nuts.

You just need to remember a few things; opening a file is fast and efficient, every time you open a file you take up resources... the smaller the file, the fewer resources utilized. Smaller files are also faster, more compact and more efficient. So, load resources only as you need them and load compact and efficient files.

There is nothing wrong with having multiple, related libraries... for example you might have user_auth.php, user_acl.php, and user_profile.php. User_auth.php might be 2-3 functions and only 25 lines of code, but you may only need those functions at login time, why have them hanging around during permission checks and profile functions?

In the end I tend to treat controllers and libraries the same as views... smaller snippets are faster and more efficient to use and take up fewer resources.
#9

[eluser]Mirage[/eluser]
[quote author="jleequeen" date="1217643818"]@Eric Cope
For instance, I might have a user controller that handles things like add, edit, delete users. It seems to me that these actions logically fit inside of a user controller. But when it comes to say, logging in a user, does that go into user/login...or does that need to be a login controller all it's own.
[/quote]

Excellent example of your condundrum.

1. I'd say it's logically unlikely that authentication requests would be handled by a controller that also handles administration (probably protected) requests for managing users

2. A separate auth controller would make most sense to me. What it allows you to do is invoke your login from any section of your site.

3. Keep in mind that your controller need not represent the actual url. You have the power of the router to re-map requests to any given controller/method.

4. The best way to keep your controllers light is to use them for what their name suggests: controlling the flow of the request, cleaning input, handing off processing to models and libraries and invoking an appropriate view for output.

5. Put repeatable tasks into libraries, utility functions into helpers and do the heavy lifting in the models to keep your controllers light.

6. Models are often mis-construed as an abstraction of the database layer. This is wrong IMO. The abstraction of the database is the Database library. It's just that Models - representing the business end of your app/site - most often connect to databases in the process. Models are the right place to errrm.... 'model' and transform the input regardless of whether it involves db access or not. Segment your models to match the backend process: users, content, blogs etc etc.


The beauty of CI is that you really don't have to follow any MVC strictness. You can refactor your code as it grows. In the end it doesn't make a difference whether you load a big controller or a big Model. Given today's hardware don't worry too much about performance implications of loading multiple small vs fewer big files. The tradeoffs are negligible in the greater scheme. What you should focus on instead is keeping your code manageable and readable by breaking it down it makes most sense to you.

Cheers,
-m
#10

[eluser]jleequeen[/eluser]
Thanks to everyone that has given me there two cents. While everyone is making good points, I'm still a little fuzzy on how to break up my app logically. Let me give another example and see if that helps explain why I'm still somewhat confused.

In my example above, I used a "user" controller. Now I totally understand why you might want to break out the authentication into it's own "login" controller. But let's say in my "user" controller I have say methods to add/edit/delete and potentially to display a profile as well. So that's maybe 3-4 methods in that controller, so that's not so bad.

But now, let's say I have a "report" controller. Now the reports part of my app is basically many forms (or screens) that make up the report. Say I have 14 forms in all that make up a report. Should I use a "report" controller and have 14+ methods in it, or should I make each form a controller on it's own. Each of these forms hit different tables in the database, so there would not be one model to be loaded that is used across all 14 screens. So is that my deciding factor on whether to group all the screens together in one controller?

Obviously writing spaghetti code forces you to put "controller" logic at the top of the file and it becomes very specific to the view of that file. Which coincides with keeping the controller small and very close to the particular view.

I just wish there were some type of best practices when it comes to breaking up your app into controllers.




Theme © iAndrew 2016 - Forum software by © MyBB