Many Varied Components, or… Multi Variable Complexity, or… Mainly Vanilla Coding
(Image comes from the Rails Envy MVC public service announcements -- and I hope they don't mind)
Here's the question:
Describe the MVC design pattern as it is implemented in Ruby on Rails.
And the followup:
In an MVC design, where would you place complex business logic?
This is part of the standard phone screen we give to potential Rails developers. The expected answer goes something like this:
MVC stands for Model, View, Controller, each of which represents a section of the application. The model manages data and often persistence, the view manages presentation, and the controller mediates between user actions and associated models and views. Each of these three subsystems should have as little interaction with the others as possible. Complex business logic should go in the model, since that is the section that deals with business objects.
If your doing a phone screen with us after this, at least have the decency to phrase that in your own words...
I don't think of that as particularly controversial, although I suppose you could pick at the wording and details to taste. Interestingly, or oddly, or something, the recent stretch of phone interviews has had a nearly unanimous answer to the followup question: Controller (sometimes, to be fair, the answer would be controller and model, but with controller as the primary answer).
After a brief time-out to check my sanity and calibrate with some other people (like the video with guys from the picture), I came out of the process with the following few thoughts:
- I have no doubt, from my phone calls, and from some Rails code I've seen in the wild, that it's very common to put complicated logic in the controller.
- I still think that's a bad idea, at least in Rails.
- Why #1: That's where the data is. Putting logic about which find methods to use and so on in the controller makes the controller too knowledgeable about the details of the model. This makes you vulnerable to changes in the model later on, and makes the controller more brittle.
- Why #2: It's easier to keep code from repeating itself if the logic is in the model -- that is, it's more likely that multiple controllers or controller actions will need the same set of logic from the model. From a maintenance standpoint, it's best to have that in one place. The logical place for that is the model.
- Why #3: In Rails, is significantly easier to unit test models than it is to test controllers.
- In my own coding, I try to limit controller code to an assignment statement that calls a model method, a single line action on a model (such as save), and logic to determine which view to call. The right hand side of the assignments goes in the model, and as much of the other logic as possible goes in helpers.
- The main exceptions to the rule is that I'll put some parameter parsing logic and the like in controller private methods, and also I'll include simple RJS stuff in an
update :pagein the controller. - It's kind of a small sample size, but I think that the tendency to put logic in the controller corresponds with a lack of test-driven development. The theory goes like this: if you are doing a reasonably strict TDD process in Rails, you tend to start in the model because that's the easiest part to test. As such, your business logic tends to wind up in the model. If you aren't using TDD, you tend to start off coding in the controller, because that's the first point of contact for the request. If you also aren't refactoring much, then your complicated winds up in the controller. Anyway, it's a theory.
Topics: Ruby on Rails
Leave a comment
About Pathfinder
Follow the Blog
-
Get a monthly update on best practices for delivering successful software.
Subscribe via email
Subscribe via RSS
Categories
Topics
Archives
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006
Blogroll
Recent
- Elements of Testing Style
- Aesthetics and Web Design
- Asterisk-Java Testing with Groovy
- 3 Misuses of Code Comments
- Fluently NHibernate
- Digging a Hole and Covering it with Leaves — The Software Development Version
- The Importance of User Experience - Do You Understand It in Your Bones?
- Writing Your Own Protocol With NSURLProtocol
- What’s In Your Dock: iPhone edition
- Feature Fatigue
