Welcome Guest, Not a member yet? Register   Sign In
View-centric design philosophy with CI
#1

[eluser]jleequeen[/eluser]
I've been working on recoding an app of mine in CI and I'm getting to the point where I'm not so sure my initial thinking of how to lay out my app was the best way. Before I began recoding my app, I sat down and roughly sketched out what made logical sense. I looked at a controller as almost the main sections of my apps (or main tabs if you want to think of it that way) then I fell into the trap of letting my menus affect how I was laying out my app. For instance, if I had a "Users" tab and it had submenu items, they became my methods which works ok for that particular thing, but not for others. For instance, I had a bunch of data entry forms, that together make up a plan a user would submit when finished. Well, in my sketch I thought it would be a good idea to create a "plan" controller and place each form as a method. Well obviously it didn't take long before that "plan" controller had a lot of methods in it and while putting a lot of things in the constructor that say more than half of the forms would use was convenient, it surely didn't make much sense to have that overhead on forms that didn't need it. Not to mention the controller code getting unmanageable (especially when you add in validation for each form).

I've come to the conclusion that, while it seems nice and tidy from a "grouping standpoint" to create a single controller that does a lot of stuff...with a lot of methods and views, it's kinda defeating the purpose of why I wanted to use a framework to clean up and structure my code better. I use to design my apps on a page/view basis..and throw the controller code up at the top of each view file, like I'm sure most beginners with php use to. But, I saw the need for structure and consistency and separation and that lead me to CI. Now, although I'm excited about what CI allows me to do along with all the handy pieces that make life easier, I'm stuck in this quandary with controllers and app layout.

I loved the view-centric design approach because it was easy and made you design from what the user interface first. I think I would be better off incorporating that approach into CI without the spaghetti code. Use CI for the separation but still design view-centric. But this would cause me to totally rethink the way I was thinking about controllers. Basically I would be looking at one controller per view. Maybe that's not such a bad thing after all. I was reminded the other day in an old article when Rasmus Lerdorf said "Keep controllers small and very close to the view". I feel like I am easily losing sight of that by having controllers that are trying to do too much.

Did anyone else have this trouble when they began using CI from a spaghetti code background. Did you began to confuse your app layout so it made sense URL wise? Doesn't it make some sense to keep things compact and neat and controllers being very specific? I realize basically what it's boiling down to, at least for me is almost what Rasmus recommended in his "No-framework Framework" post that I'm sure everyone has read. Instead though of just using separate include files to split up my code, I'd rather use CI.

I'd love to hear everyone's two cents.
#2

[eluser]Colin Williams[/eluser]
The way I approach it is quite simple. First I ask, "What are the components of this application?" Well, there are users, there are pages, there are categories, there are comments. Right there I see at least 4 controllers brewing. Then I ask "What do these components do, or what can be done to them/with them?" and I break down the actions for each controller. This usually starts with the 4 CRUD operations and goes from there.

page/view
page/add
page/edit
page/delete
user/add
user/edit
user/delete
user/login
user/dashboard
user/profile
comment/add
comment/delete
comment/view
comment/history/uid

I've also seen it approached the other way before, where you build controllers based on the operations. So for instance, you would have an Add controller, an Edit controller, a Delete controller, and so on. I went this route once and it certainly has its benefits, so it might be a direction you consider.

add/page
add/user
add/comment
edit/page
edit/user
edit/comment

You should certainly have the final menu/URL structure for your application in mind from the start, but build the app in such a way that each component is self contained and controlled.
#3

[eluser]jleequeen[/eluser]
I see the value in your approach and that is exactly how I started thinking about my app when I began to sketch things out. But once I guess coding began, I realized some of my controllers were getting ridiculous in size. Obviously what looks good on paper sometimes doesn't translate once put into practice. I guess I also had the problem of wanting to apply an approach that is consistent.

In your example you have the user controller with 6 methods in it...which when I used the same kind of design in my app I had about 10 methods. I know 10 methods is not a huge amount, but I started to realize that I was putting a lot of stuff in the user controller and it was getting bloated. I guess because in actuality, I was thinking, A user can do this and this and this and this....and eventually I realized most of my app could fit inside the user controller. So then it is refactor and break up the user controller. It's seems it can get easily messy when I started thinking in terms of users actions vs how the database might guide me into breaking up my app.

I know about fat models and skinny controllers to help minimize controller code, but I guess it's applying a consistent approach. But from an app layout perspective I thought I had a grasp on things but I keep second guessing my approach. Maybe I should design more from looking at my database (or data I should say) and that would lead to your point about building it in a way were each component is self contained and controlled.
#4

[eluser]Colin Williams[/eluser]
Well, sure, users can do a lot of things, but only the things a user can do with users should go in the User controller. Users can add pages, add categories, but pages and categories are their own objects. Hrm.. objects... Makes a lot of sense to have one controller per object, at least as a start. Then you just restrict the scope of each controller to its own object as much as possible.

I'm not sure I would get too concerned with the amount of methods any given controller contains, so long as you aren't repeating code when it makes more sense not too. I do agree that each method should remain fairly slender, putting a good amount of heavy lifting on the model, but again, only when it makes sense. Sometimes a controller method has a lot to, well, to control. Imagine a cart/checkout controller method:

1. Read the cart items
2. Build the order
3. Validate checkout form
4. Possibly add new customer data
5. Send order to payment gateway
6. Save order to database
7. Email store admin
8. Build invoice
9. Email customer the invoice
10. Show success screen

And that example doesn't even show exception handling, since any step along the way could fail. Size doesn't always equal bloat
#5

[eluser]jleequeen[/eluser]
I agree with you Colin that sometimes thinking of it in terms of objects makes sense and that's how I initially figured out my sketch of the app. But that ultimately led me to thinking in terms of my database and I think that is where I get inconsistent. Obviously in your example of a cart/checkout controller method, there is not a "cart" table...or a "checkout" table in your database. So that doesn't fit in quite the same way as if you had your "user" table and make a controller for that table. So maybe my confusion lies more with creating controllers that make sense to the app, but not necessarily to the database, if that makes sense. I guess when thinking about what your objects are, they don't necessarily correlate with the database, even though in some instances that may make sense.
#6

[eluser]Colin Williams[/eluser]
There actually is a 'cart' table Smile, but I still think that your main assumption is correct. Just keep the separation logical, whether there's a corresponding object or not.




Theme © iAndrew 2016 - Forum software by © MyBB