• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Some questions concerning MVC pattern in a CI application

#1
[eluser]plainas[/eluser]
Ok, my application is starting to get complete and here and there I stepped on some dilemmas that I wouldn't like to face next time.

I read somewhere on some article about rails (if I remember correctly) that going for a megalithic (monolithic) controller was a bad strategy and should be avoided.
I was stupid enough to follow this advice and I forced the splitting of what should naturally be a controller into two controllers just because it was reaching 600 lines of code.
That was a mistake because I latter found myself creating workarounds to fetch stuff that could be reached simply by reference to the controller class in case I would use only one controller.

Now, the question is not, when to use more than one controller, its more like: what should a controller contain and what motivates the creation of another controller?
I would like to ear different opinions on this.
Personally I won't repeat my mistake. Unless I have a set of features on my application that will use a totally distinct part of my database, I will wrap everything on the same controller.

Other kind of dilemma I had was where to draw the model-controller and controller-view boundaries.

Like, the vies support loops, but what should the loop contain. For example, lets say I want to output an HTML table. I can prepare each row on the controller and then simply loop trhough them on the view. Or I can put the elements into an array and then add the HTML tr and td tags as i loop in the view. Or I can prepare the whole table in the controller and then just place it in the right spot in the view.

The same aplies to the model, how raw should the data be in the controller? Using the controller just as a database end point makes it kind of useless. On the other hand, too much data prepp, sanitation, etc. in the model will bring to much application logic into it making the controller a bit confusing.

I guess these are mostly a matter of personal preference. Anyway, any tips for good application design usgin CI?

#2
[eluser]Colin Williams[/eluser]
One day, Request comes to town and it asks for a specific blog post.

It is greeted by the Blog controller, who makes sure everything checks out and passes the params that Request has brought along to Blog_model.

Blog_model goes to the database in the back and returns with a post.

Blog controller takes the pieces Blog_model returned and then worked with Views to piece it all together.

Finally, Request ended up with a nice package to send back to the Client.

* * * * * * * * * * * * * * * * * * * * * * * * * * * *

Okay, so that might seem a bit pejorative to you, but the point I'm trying to make is that each piece is sort of an actor in a little scene. The controller is sort of the concierge for the HTTP request. In the scenario above, the controller was responsible for handling a blog object. The process was pretty simple, but imagine a Cart controller that was taking an order. It would have to build the order, generate the total, validate the payment, pass the payment to the gateway, handle the response, save the order, email the customer, email the store owner, and generate a receipt for the user, among many other things.

Controllers can sometimes be thought of object handlers, one for each unique object of your application. Blog posts, tasks, products, carts, categories, users: These are the kind of "objects" that would probably each get it's own controller.

So the point is, sometimes the Controller has a lot to do, so it's bound to get bloated in some cases. Models retrieve and format data, whether the data comes from a database, flatfile, or web service call. And a View formats the objects for display.

Controller: Handle request for objects (or actions on objects).
Model: Retrieve objects.
View: Format objects for display.

Just don't mix those roles, and you should be safe.

#3
[eluser]Bramme[/eluser]
You've got that in copy/paste ready, right? :p

#4
[eluser]Colin Williams[/eluser]
Yeah, I think someone needs to write a greasemonkey script that scans the current topic and provides you a reservoir of your previous responses to select from. It's like clockwork on these boards because no one seems to know how to search!

But I did forget to mention a slightly altered approach. Instead of an object/action scheme, some like to use an action/object scheme.

So instead of

blog/save
blog/retrieve
user/save
user/retrieve

.. one does

save/user
save/blog
retrieve/user
retrieve/blog

Either can be useful, although some swear by one or the other.

#5
[eluser]Darkbob[/eluser]
I see controllers in codeigniter as Facades which should be created using the GRASP "controller" pattern.

This pattern states that the "controllers" should be a root object or a class representing a receiver or handler of all system events of a use case scenario.

In your case, administration events is a suitable use case. For this reason, a single controller for it make sense.

As for doing "alot" of application logic in the model, this is EXACTLY what you need to do Wink
In fact, the controller should delegate everything to the domain classes. It should *NOT* do any application logic. Models are not there to load object from database. You do that only if you use direct mapping which is normally use when you have a static database schema. If you always do direct mapping, it lowers the classes cohesion.


By the way, you should always do as you said; pass the data array to the view. the controller is only there to delegate actions, if it creates html, MVC is broken.

#6
[eluser]Randy Casburn[/eluser]
Holy Malarky Batman! It's someone I can talk to!

@DarkBob - Hi, I think maybe the problem you'll run into applying a strict UC OOP model driven design approach to CI is the fact that CI is not all that OO. While the GRASP pattern makes a compelling story and I'm there with you (I model my apps this way where it makes sense -- UC by UC, it is not always practical).

As an example, CI's front controller is quite procedural by design and has no OO properties at all. While it instantiates the architecture, it accepts the "system events" procedurally and not in an OO fashion. These are then forced through to a secondary controller that only then handles the UC flows. You won't find other traditional GRASP mechanisms in CI such as protection patterns and the like either. Coupling is quite loose mainly due to the light treatment of OOP.

I hope you find this helpful.

Randy

#7
[eluser]Crafter[/eluser]
Quote:Now, the question is not, when to use more than one controller, its more like: what should a controller contain and what motivates the creation of another controller?

A controller should represent a business object that you can represent in your application. For example customer, blog, product, user ....

Each object has actions that are allowed. For example, a product can be created, modified, looked-up, booked, purchased, returned, .... These actions will be your controller methods, and be accessed as
http://mydomain/product/create/
http://mydomain/product/reserve/
http://mydomain/product/buy/

Your controller method will contain the details of who, why etc. For example, only a staff member can create() a product, a customer can only buy() is there is sufficient stock, and so on.

Quote:Other kind of dilemma I had was where to draw the model-controller and controller-view boundaries.

In order to consider your model, you need to visualise a scenario where your data is stored and controlled by a party that you have no control of (for example another company). In this case, they keep your data, understand where what is (not necessarily what it means). In addition, the relationship between you and the data-handling company must be structured and agreed beforehand, so that they can give you the data that you require.

That same thinking goes into the view. Here you pass the processed data to some party that presents them as they need to. You are not interested in how they ensure that a cellphone, Mac, and PC all see the same information - that is their problem.

At the same time, this sets the rules for the interaction, The data company gives you the product details, you determine if you want to sell it and what to say to the customer. The customer facing company gets your decision and presents it to the customer. In the same breadth, the data management party is not allowed to pass information directly to the data presentation company.

So the MVC paradigm (theoretically) allows for the total separation of your applications into layers, which function and inter-relate in a structured and independent way. In reality, while you might be all those parties, during design time, you need to put on those different hats.

Regards
Pradesh


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2019 MyBB Group.