• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
MVC - Controller Questions

#1
[eluser]jleequeen[/eluser]
Is there really any benefit to having non related functions in the same controller? I ask this because I'm trying to understand why it's a good thing to have a controller with 10 functions in it that don't necessarily have anything to do with either other. To me a controller just shouldn't contain anything more than it needs for that request. Let me give an example.

A user controller has:

user/login
user/logout
user/profile
user/save
user/delete
etc...

Now to me, it seems like you wouldn't want login code in the same file that shows a user profile. I realize you could have a auth controller that handles login/logout, but my point is, some people do just this because they design based on "objects" You could just as easily have a blog controller but have 20 different methods in that controller that does many different things. It just seems that on each request, you should have mostly code specific for that request, not a lot of other functionality stuck into the controller that does other things, but that code has to get loaded on every request. Just seems a little too much overhead to me.

I realize in the MVC way of doing things, it's easy to design starting with objects and those become your controllers. But designing this way to me seems to put too much overhead in a single controller. In the old page based approach I would have a login page which would be specific for the login request. No other "extra" code stuck in there.

Is designing controllers based upon objects just done mainly to "group" seemingly like actions together, even if they don't need to be used on each request? Seems a little inefficient to me. Also, what happens (if you design user interface first which is what I normally do) things don't fit nicely into the "objects make your controller" approach.

It seems like I should be using the page based approach design principles I've always used to develop the views (interface first) and then use a controller per page (view) approach that accomplishes my efficient code per request.

Does this make sense or am I missing the boat entirely and should adopt the stuff 30 methods in a controller even if they aren't needed on each request mentality?

#2
[eluser]Randy Casburn[/eluser]
You've generated what will amount to a religious diatribe of beliefs about your topic...but hey, it's all in fun right.

Your thinking is correct. The Controller in a classic MVC design pattern was originally established to employ an observer pattern that would receive events from the UI componentry of the application and that observer pattern implementation would invoke the controller in order to respond in specific fashion to the singular event presented by the observer. So, yes you are correct.

Since these things all happened in a tightly coupled environment, or at least a tightly controlled environment, all the parts and pieces were well understood. In today's web based environment it can be argued that the observer for HTTP event is your web server implementation (Apache, IIS, etc.), that the JavaScript interpreter in your browser maintains it's own observer through it's own event manager, the PHP virtual machine (interpreter) has it's own observer and finally CodeIgniter's front controller (codeigniter.php) acts as the observer for CI.

Reacting to all the variations in event management characteristics may, in fact, require a CI controller to react differently depending upon the characteristics of the event. An overly simplistic example of this is demonstrated by the fact that both the web server and CI have implemented responses to the inevitable "page not found" event. In the classic synchronous (tightly coupled) environment this duplication would not be necessary.

I agree with you that designing controllers as classes that create functional "objects" is a flawed design approach. If this is what has happened, it would seem to indicated this capability is more appropriately established as a class in a library that is instantiated from within a controller when needed. But you should immediately notice that the class must be instantiated. Ah, so no performance is gained anyway since the entire object must be constructed anyway.

All this for a script that is going to live for approximately....0.04435 seconds

Let the deluge begin ;-)

Randy

#3
[eluser]Rick Jolly[/eluser]
Same topic here: http://ellislab.com/forums/viewthread/89573/

I'm with you. 1 controller per view almost exclusively and controller and corresponding view named identically. Less code to load, more flexible urls, and consistent intuitive organization.

#4
[eluser]jleequeen[/eluser]
@Rick

That makes the most sense to me, but it seems more and more I'm seeing examples where someone creates there URL structure on objects they've derived from their DB. To me, views can pull data from one or many models and break down really easily when you by default create a controller because you've added a new table to the database and want to put all that functionality into that table.

I'm just curious since you do use 1 controller per view almost all the time, do you end up with urls like the following?

http://www.yoursite.com/user_login
http://www.yoursite.com/user_profile
http://www.yoursite.com/user_list

or do you do subfolders where you can have user/login etc.?

Just curious?

#5
[eluser]Colin Williams[/eluser]
You can diminish the Controller's role all you like if it serves your desired design. I think there are two ways to structure controllers: By object, by action. I think most people have object-based controllers, but action-based controllers can serve well, too, so long as you don't mind objects being handled in multiple files. If you think of something like Wordpress, all it's controller really does for the front-end is decide which view to load. It is then the views that are tasked with figuring out what to show by communicating with the models. I don't think this is a bad way to design the "designable" public-facing/front-end of your application. If you were going to write a blogging or CMS in CI, this might be an approach you take. Inventory management, project management, financial management apps, etc., might benefit from a slightly different approach since there's probably more business logic happening for all requests.

You are certainly right that for any large-sized application, you can't be cramming repeated code into each Controller you write. The challenge is how to pull these global actions out of controllers. There are various ways to do this, and CI is properly designed to do this (with libraries, extending the Controller class, or hooks).

#6
[eluser]jleequeen[/eluser]
@Colin

I see what your saying. When I first started with CI objects were what I thought of. Unfortunately I had very little OO experience so it's taken some time to grasp the entire concept. Coming from a procedural page based approach background and never having used MVC has made for a tough introductory. But I do understand most of the concepts and I wouldn't be here if I didn't want to write better code. I'm sure once I have a couple of apps under my belt it will really help me hone in my skills.

Obviously for me, views are easy, models are easy, but the controllers have been the sticking point. It makes sense if you are designing by objects, to have everything in one controller. Maybe my problem with objects based design is I'm stuck on page based approaches and that has obviously made me design by a actions based approach.

Maybe part of my problem is deciding exactly where I get my objects from. I guess that is why some prefer to use there database to help them figure that out. Even that can be confusing for me though because a database does not always tell me about objects that I may need. As in an earlier post in another thread you mentioned what all a checkout method of a cart object might do. If you had no cart table in your database, say, you had a table named order and order_details, etc. How did you decide to create a "cart" object. Do you look at your app during planning and ask certain questions to come up with these domain objects. For instance, the app needs to have a way to login/logout. Then you ask yourself, who does those actions, and come up with a "user" object. That's an easy example and I can understand that. But what about say... you have several reports that will be generated by numerous tables in your database. Obviously there is no "reports" table. Would you decide that "Reports" should be it's own object and each report would be a method, or would you have some other methodology of deciding how to group those reports, or would they stand on there own? I'm guessing that you would create a reports object and make each method a report. Oh and one other thing I have a question in regards to. Say you are creating an application and you have come up with all the domain objects that will interact. Where would you put something simple, like...a public facing view like a homepage, or about us page. These obviously may not fit into a domain object, so do you go ahead and create a controller for each one and make them domain objects? Just curious, because most of the apps I build always have a public piece along with the backend stuff.

Damn, I've written much more than I anticipated. In conclusion I suppose it's coming up with those domain objects that I need to work on. Unfortunately, not everything fits the "object/action" way of thinking, or maybe it does, the challenge as you said is coming up with how to fit these things together in my world (app).

By the way, awesome screencast series you started on Advanced Form Handling. I look forward to the continuation of it.

#7
[eluser]Colin Williams[/eluser]
Quote:How did you decide to create a “cart” object.

The cart, for one, is how the user understands the process. Now, behind the scenes, in the code, we don't necessarily have to apply the same mental models we give our users, but in that case it works. The cart ties products to orders. In the real world it almost already plays a controller role. But this does not mean there's not a products controller neither an orders controller.

Quote:Obviously there is no “reports” table. Would you decide that “Reports” should be it’s own object and each report would be a method, or would you have some other methodology of deciding how to group those reports, or would they stand on there own?

Either and both. It depends on the specifics. There certainly would be one 'reports' controller that does the common stuff, like shows a list of reports, shows a single report, searches reports, etc. But there might be a need, if the reports are unique enough, to have a controller for each type of report, and equally a model. The better way, IMO, is to have one core Report controller, then have report "plugins" that extend the functionality of the Report controller in appropriate contexts. Just some pseudo code here shows you how you can use libraries to act like plugins or modules:

Code:
class Report extends Controller {
    
    function Report()
    {
        parent::Controller();
    }
    
    function add($type = 'basic')
    {
        $type = strtolower($type);
        $type_lib = $type .'_report';
        if (file_exists(APPPATH .'libraries/'. ucfirst($type_lib) . EXT))
        // If there is a Type_report.php library
        {
            $this->load->library($type_lib);
            // Now we relegate operations to methods that the libs should have implemented
            if ($this->$type_lib->run_validation())
            {
                $this->$type_lib->save_report();
            }
            else
            {
                // Load the view, form, etc... typical validation
            }
        }
        else
        {
            $this->error = 'No support for '. $type .' reports.';
            $this->add('basic');
        }
    }
}

Quote:Where would you put something simple, like…a public facing view like a homepage, or about us page.

Likely in a simple Page controller. Could just load views or flat HTML files to get the page text and not need it in the database


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


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