61

I have been coding for a while, but mostly scripts and simple applications. I've moved into a new role where it is all about developing Web Apps and using a proper MVC architecture, so I am desperately trying to learn about all that very quickly.

I hope this question is not too similar to "Best Practices for MVC Architecture" but as I am going through a few different tutorials, I noticed that some have multiple controllers for different things.

How many controllers does a single web app need?

I realize this would be difficult to answer without an example so I'll provide one:

Application:

  1. User logs in.
  2. User can do one of three things:
    a) Upload a file (stored in a mongodb database with meta data).
    b) Search for a file.
    c) Log out.

My question is a general one, but I gave the example to help out anyone trying to answer.

1
  • 12
    A really nicely asked question. Commented Aug 13, 2013 at 17:03

8 Answers 8

34

For your example I would create two controllers:

  • Sessions Controller for Login and Logout (create and destroy session for REST like layout)
  • Files Controller for everything on files (index=search and create=upload)

In general a RESTful approach where you think about everything as a resource that can be displayed, created, edited and destroyed gives you a good idea how to structure things. As you can see from my examples I don't stick too close to every single verb in REST.

You would most likely need more controllers for further functionality. For example a Users Controller where users can create new accounts. And in addition to this you would need an admin interface where you can edit the resources with higher privileges. In such a case it is quite common to have nearly every controller duplicated.

A very very rough estimate to get an initial idea could be one controller for every table in your database that users can access. But this is really only a very crude measurement.

2
  • 3
    Taking your admin example: Would the admin controller extend the general user or would you completely redefine all the methods? For example, maybe all users can upload and search but only admins can delete. Would the admin controller class just inherit all the general user methods?
    – Jeff
    Commented Aug 13, 2013 at 13:38
  • 4
    This really depends a lot on actual functionality.But in general I simple write a second controller without any inheritance at all. Following the 'thin controller' principle there should not be much code in a controller anyway. And the admin controller can be especially simple. All important functionality goes into the model. (eg if deleting a user means all his files should also be deleted then the model handles this, there isn't a single line for this in the controller) Commented Aug 13, 2013 at 13:44
6

It really depends on the web app. In your example, one is probably sufficient. If you were to implement a full blown ecommerce app with shipping, tax, inventory management, tiered pricing, etc., then you just might want to have a couple more.

If your controller suffers from one or more code smells (especially Large Class or God Object) then you know you're probably past the point where just one will do.

5

It really depends on your application needs and architecture of business modules.

A general rule of thumb, number of required controllers depend on a number of modules and sub-modules in the Web app.

As a complementary, it would be helpful to organize the controllers into Areas. The concept of Areas is build into the ASP.NET MVC framework and it simplifies the organization of controllers that serve one module.

There are a number of related discussions:

2
  • 1
    Great references! I'll be sure to check them out!
    – Jeff
    Commented Aug 13, 2013 at 14:04
  • Sure, no problem.
    – Yusubov
    Commented Aug 13, 2013 at 14:07
4

I like Apple's way of doing it.

Every view is controlled by only one view controller. ~View Controller Programming Guide for iOS

The idea is that you should be able to easily swap out Views. IMO, by only having 1 Controller per View it makes it easier to accomplish this. But I'm sure you could have a Controller with multiple Views and still design it so you can switch Views without changing program logic.

6
  • That is a good point, but would you need to have a controller for every view plus additional ones to take care of things like users? I also guess if my project were bigger it would make more sense to have more controllers.
    – Jeff
    Commented Aug 13, 2013 at 14:10
  • Models should keep track of users. So multiple controllers can all use the same model object if necessary. Commented Aug 13, 2013 at 14:11
  • 2
    So a controller has a Model object and a View object. The Controller asks the Model object for information (like User Information) and then sets the View accordingly. The Model should have most of the program logic while the Controller just has the logic to be able to communicate back and forth between the View and the Model. Commented Aug 13, 2013 at 14:16
  • 2
    One controller per view is very limited design, as your controller would not be able to display different view-models, for different states of the Model.
    – Yusubov
    Commented Aug 13, 2013 at 14:30
  • 1
    @ElYusubov I can see where it could be confusing. In iOS every view has only one view controller and every view controller has only 1 active view (and that view can have sub-views) but that view controller can also contain references to any numbers of views. Commented Aug 13, 2013 at 14:42
2

One example that I like is thinking of a thermostat. A thermostat is a great visual for viewing the MVC pattern.


On an older, analogue thermostat you can picture things like this:

View - The temperature reader, which displays the current temperature.

Controller - The dial, where you change the temperature

Model - The parts inside that are invoked by the controller that cause the temperature to change.


You should always abide by designs that allow loose coupling and limit models and their associated controllers to a single task, and you should use as many modules/controllers as you need. Depending on the size of your application, you may have far less views than you do models and controllers. This is to be expected with any large size application. Good Object-Oriented Programming is characterized by loose coupling, encapsulation, inheritance, and polymorphism. Not all languages support polymorphism to the same degree (function, method, operator overloading / overriding).

If you want to have a better understanding of employing the MVC architecture properly, consult the GoF "Design Patterns: Elements of Reusable ... Software" which uses C++ and SmallTalk for example code. This book is not the alpha and omega, but it's certainly a start!

Good luck!

1

I assume that your example will evolve into a complex system.

Application:

User logs in:

  • LoginController

Its sole responsibility is to handle logins, re-direct or notify user of the outcome.

Upload a file

  • UploadController

I assume here that you want to upload any type of file. If at later date you decide to upload MP3s and PDFs, then I'd have a base UploadController, MP3UploadController and PDFUploadController.

Search for a file.

  • SearchFileController

This would suffice for a basic requirement. You can have multiple search controllers at a later date depending on how complex the search logic becomes. The last thing you want to have is a single SearchController with 20 action methods performing different searches.

Log out.

- LogoutController.

One might consider this to be an overkill, but I don't think it is. I think it's clean and nicely separated.

If I were to look at this project structure, I would instantly know what it does and how it's structured. To take it a step further, I would put LoginController and LogoutController into separate area.

I've developed something like this before and it worked really well.

5
  • Thanks for the input! Got any working code? getting stuck on a few things.
    – Jeff
    Commented Aug 20, 2013 at 18:00
  • What problems are you experiencing?
    – CodeART
    Commented Aug 20, 2013 at 21:11
  • I am able to upload a subject and a date (in string format) but cannot upload the file itself (see stackoverflow.com/questions/18344614/…).
    – Jeff
    Commented Aug 20, 2013 at 21:33
  • I'm a .NET developer. Sorry I can't help you out.
    – CodeART
    Commented Aug 21, 2013 at 7:12
  • I know this is an old post, but coming for an ECB background, this by far what made sense to me. I have a question and I hope u can correct me if im wroing, I was wondering where these files should reside, I've seen multiple examples where a single controller script is used to contain all of these controllers, my approach would have been to create a script for every controller class and place them in a folder names "controllers", what do you think of this? Commented Sep 6, 2022 at 22:51
1

Most of your code would be happening in a business layer right? If that's the case then all you are really doing in your controller is returning data to the view.

Not really sure if I'm a fan of separating the controllers into subtypes. Whilst you should maintain separation of concerns I think subtypes is going a little too far. Also you need to be careful in cases where heavy objects are initialized in the constructor or a controller. For example: in your example you would want a heavy object, used only for search/upload file to be released when the user is on the login page.

It's better to have a controller per logic unit, for example AccountController (login, registration, logout), FileController (search, upload) and so on.

0

In general you may say that every MODEL has its own CONTROLLERs and dedicated VIEWs. By saying general I mean that this is the best practice.

application Aspects (like user management) should be translated to application service and need to be called by the controller it self, or to wrap your controller (using attributes that make the controller functionality "visible" according to request user role, for instance).

Remember that all controllers should basically handle CRUD operations over model and use different views for different filters.

In my opinion one of the major advantages of MVC as pattern is that it deliver the best way to tie models and views.

About the example you added: I would create 2 controller: one for the all user login operation (register, login, logout etc.) and the second for file operations (Upload and search). note that the first should also be backed up with some Aspect related to the Login functionality and the second is ordinary controller

2
  • without an explanation, this answer may become useless in case if someone else posts an opposite opinion. For example, if someone posts a claim like "Managing user roles and authorization should not be on top of the controller", how would this answer help reader to pick of two opposing opinions? Consider editing it into a better shape
    – gnat
    Commented Aug 21, 2013 at 13:34
  • 1
    @gnat I accept your comment, see the edited answer Commented Aug 22, 2013 at 17:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.