Tuesday, 12 June 2012

MVC: Do and Dont's

Controller - The "C" in "MVC"

The Controller's job is to translate incoming requests into outgoing responses. In order to do this, the controller must take request data and pass it into the Service layer. The service layer then returns data that the Controller injects into a View for rendering. This view might be HTML for a standard web request; or, it might be something like JSON (JavaScript Object Notation) for a RESTful API request.
Red Flags: My Controller architecture might be going bad if:
  • The Controller makes too many requests to the Service layer.
  • The Controller makes a number of requests to the Service layer that don't return data.
  • The Controller makes requests to the Service layer without passing in arguments.
If the above "red flag" conditions start to happen, then I probably have a Controller layer that is doing too much. I should probably factor the logic out into a more cohesive Service layer that can be invoked by the Controller. Furthermore, if the Controller is making requests to the Service layer without passing in arguments, then I may have a Service layer that is breaking encapsulation (ex. referring to the Session, CGI, FORM, or URL scopes).

View - The "V" in "MVC"

The View's job is to translate data into a visual rendering for response to the Client (ie. web browser or other consumer). The data will be supplied primarily by the Controller; however, the View may also have a helper that can retrieve data that is associated with the rendering and not necessarily with the current request (ex. aside data, footer data).
Red Flags: My View architecture might be going bad if:
  • The View contains business logic.
  • The View contains session logic.
If the above "red flag" conditions start to happen, then I probably have a View layer that is doing too much. Business logic should be factored out into a Service object. And, session references should probably be factored out into a Helper object or a Controller. This will make the Views easier to build and to test since they rely solely on data and not on an entire application being in place.
NOTE: View rendering is something that I am still fuzzy on. My current approach uses a CFM-only approach to rendering; as such, integrating Components into a view rendering lifecycle is still something that I need to think about.

Model - The "M" in "MVC"(It can be a webservice, your repositories, your service classes or simply your domain models. The Model are everything that are used to get the information that you need. )

The Model's job is to represent the problem domain, maintain state, and provide methods for accessing and mutating the state of the application. The Model layer is typically broken down into several different layers:
  • Service layer - this layer provides cohesive, high-level logic for related parts of an application. This layer is invoked directly by the Controller and View helpers.
  • Data Access layer - (ex. Data Gateway, Data Access Object) this layer provides access to the persistence layer. This layer is only ever invoked by Service objects. Objects in the data access layer do not know about each other.
  • Value Objects layer - this layer provides simple, data-oriented representations of "leaf" nodes in your model hierarchy.
Red Flags: My Model architecture might be going bad if:
  • The Model contains session logic.
  • The Value Objects retain (ie. store) references to Service objects or Gateway objects.
If the above "red flag" conditions start to happen, then I probably have a Model layer that is breaking encapsulation. By letting the service layer refer to sessions, I am also creating a Model that is hard to test without having an entire application in place. Furthermore, having session references in the model makes the model incredibly hard to reuse across different controllers (as per my web/API split mentioned earlier).

No comments:

Post a Comment