9

Often when I design a program with MVC, the controller is useless half of the time.

What I mean is this: something happens on the view (e.g. a button click). The view then notifies the controller. The controller then directly delegates to the model and does nothing else because it has nothing to do.

For example:

User presses button 'Color Blue' > view tells controller controller.colorBlue() > controller tells model model.colorBlue() > model colors something blue.

In this example, the controller seems useless. It adds nothing. The view might as well have talked straight to the model.

The other half of the time, however, the controller does do some kind of mediation between the view and model.

My question is this: how common is this in MVC structures? Is it reasonable that half the time my controller seems unnecessary? Or is this a problem? Is this common? How should I approach this?

If my question isn't clear enough, please say so.

1
  • 1
    as hinted by RobertHarvey though, for this particular example, it might be better if controller.colorBlue() actually then calls model.setColor(0, 0, 255);. One reason for separation between Model and View is that it is often the case that you have multiple UI elements to represent a single state in the model (e.g. an item is checked in the menu, the toolbar is depressed, and pointer changes to a fill icon all corresponds to the currently selected tool field in the model), with MVC separation the model would not have to worry about synchronizing the different UI elements.
    – Lie Ryan
    May 7, 2014 at 22:07

2 Answers 2

12

You're underestimating the importance of having a layer of abstraction between your User Interface and your Model. The Controller fulfills this function 100 percent of the time.

Your example model.colorBlue() is a bit specious. In a real model, this would probably be a CRUD method. So your button might be a Create Customer button, your controller method would be CreateCustomer() and your Model would be CreateCustomer(). Sure, you're just passing through the call.

But what if you needed to change the way the model works? If your View were calling your model directly, your application will break if you change the Model. Controller methods provide an "access point" for your View; you can make a simple modification to the controller method, perhaps by changing the Model call to CreateCustomerWithVerification(), and everything still works.

The same reasoning applies for having a Service Layer. Instead of simply having CRUD methods in your model, you should have business actions. That way, you keep business logic out of your controllers, and make it possible to use the Model somewhere else, perhaps in a WPF application.

Think of the Controller as a "Switchyard." It should be a go-between, mediating requests between your UI and your Model, but controller methods should have as little logic in them as possible.

10
  • Let me see if I get what you're saying. You're saying that even if the controller simply delegates straight to the model, it's still good to have one between the view and model becasue of this: if the model changes, all the objects calling it's methods might have to change. If the view is the one that calls methods on the model, it'll have to change. If the controller calls the methods, it'll also have to change. But the difference is that the view is responsible to display the UI - an important piece of the app. The controller's only responsibility, however, is exactly this - communicate [..]
    – Aviv Cohn
    May 7, 2014 at 21:34
  • with the model. And because of this, it's better to change the controller when the model changes (and leave the view the same), then change the view.
    – Aviv Cohn
    May 7, 2014 at 21:35
  • 3
    Yes, that's exactly right. The separation provided by the Controller layer allows changes in the Model without breaking the UI or the routing. May 7, 2014 at 21:35
  • I see. And just to be sure: it's better to change the controller than the view when the model changes, because the view is responsible for important logic - displaying the UI. Changing it theoretically puts all it's other code at risk. However the controller's only purpose is exactly this, communicate stuff to the model, and thus depend on the model - so the view doesn't have to. And because the controller does not include any other important logic, it's better that the controller changes when the model does, than the view having to change. Is this accurate?
    – Aviv Cohn
    May 7, 2014 at 21:38
  • Yes, essentially. By isolating such changes to the API surface of the Model and the controller methods, you provide better decoupling from the UI. The View should never have to change as a result of a change that occurs to the business logic, unless the View also needs to reflect the changes in the way the business operates. To put it another way, the View should have as little knowledge of the Model objects as possible; this is why we have things like ViewModels (which provide additional decoupling from the Model). May 7, 2014 at 21:40
-1

While coding you could think this way:

  • Will I be able to change view to something else (console, service) or you same controller for different view?
  • Will I be able to change model to handle different database or write to some external service?

In your case it seems you are putting domain logic into model and that would cause you problems if you want to change it: you will have to copy methods like "model.colorBlue" to new model.

And what would happen if definition of "blue" changes? You will have to change it 2 models. Also in controller you should not write directly into your database, but as Lie Ryan pointed you should use model.setColor.

Same with views. If you start putting logic or validation into view then if you want to change view you will have to copy all that functionality.

Your Answer

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

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