Object-oriented – MVC: Does the Controller break the Single Responsibility Principle

designmvcobject-orientedsingle-responsibility

The Single Responsibility Principle states that "a class should have one reason the change".

In the MVC pattern, the Controller's job is to mediate between the View and the Model. It offers an interface for the View to report actions made by the user on the GUI (e.g. allowing the View to call controller.specificButtonPressed()), and is able to call the appropriate methods on the Model in order to manipulate it's data or invoke it's operations (e.g. model.doSomething()).

This means that:

  • The Controller needs to know about the GUI, in order to offer the View a suitable interface to report user actions.
  • It also needs to know about the logic in the Model, in order to be able to invoke the appropriate methods on the Model.

That means that is has two reasons to change: a change in the GUI, and a change in the buisness logic.

If the GUI changes, e.g. a new button is added, the Controller might need to add a new method to allow the View to report a user press on this button.

And if the business logic in the Model changes, the Controller might have to change in order to invoke the correct methods on the Model.

Therefore, the Controller has two possible reasons to change. Does it break SRP?

Best Answer

If you continue consequently to reason about the SRP you will come to notice that "single responsiblity" is actually a spongy term. Our human brain is somehow able to distinguish between different responsibilities and multiple responsibilities can be abstracted into one "general" responsibility. For example, imagine in a common 4 person family there is one familiy member responsible for making the breakfast. Now, to do this, one has to boil eggs and toast bread and of course set up some healthy cup of green tea (yes, green tea is best). This way you can break "making breakfast" down into smaller pieces which are together abstracted to "making breakfast". Notice that each piece is also a responsibility that could e.g. be delegated to another person.

Back to the MVC: if mediating between model and view ist not one responsibility but two, then what would be the next abstraction layer above, combining those two? If you can't find one you either didn't abstract it correctly or there is none which means you got it all right. And i feel that is the case with a controller, handling a view and a model.