Welcome to Giant Robots Smashing Into Other Giant Robots — a weblog about development, business, design and technology — written by thoughtbot.
views gone wild
The pragmatic programmers dave and andy once summed up object oriented programming in 1 sentence: “Keep it DRY, keep it shy, and tell the other guy.”
We all know DRY (mostly thanks to Rails now). We just discussed tell the other guy. But this time I want to touch on “keep it shy”.
Now “keep it shy” (a.k.a the law of demeter) is about coupling. An object is coupled to another object whenever it depends on it. Being dependent means sending a message to another object. So there has to be some coupling in a system or nothing would ever happen i.e. each object would stand on its own. However, having too much coupling results in a system were you make 1 change and you break all sorts of other things that were dependent on it. Objects were designed to hide implementation and avoid situations like that. But you still have to be disciplined in keeping your objects implementation hidden and not giving it out to any object that asks for it. And at the same time, not asking an object for too much of its stuff (i.e. implementation).
For example:
1 2 3 4 5 6 7 8 9 10 11 |
class Event < ActiveRecord::Base belongs_to :address end class Address < ActiveRecord::Base has_many :events end |
Now somewhere in a view we have the following code:
<%= @event.address.street %> |
Now that view is coupled to the Event class’ implementation, specifically its dependent on the fact that Event#address returns an object that understands #street. Should we ever change that, this view would break.
If we want to keep it “shy” we’d have to write a wrapper method on Event:
1 2 3 4 5 6 7 8 9 |
class Event < ActiveRecord::Base belongs_to :address def street address.street end end |
<%= @event.street %> |
However, now we realize that the Address class is un-necessary; we normalized a little too much. So we scrap it and our schema goes from:
events (id, title, address_id) addresses (id, street, city, state)
to:
events (id, title, street, city, state)
And our Event class becomes:
1 2 |
class Event < ActiveRecord::Base end |
<%= @event.street %> |
Because we wrote our view code “shy”, it was in no way dependent on the implementation of how Event stored its address information. We were able to change the implementation of Event and we didn’t break the view; great, now thats what objects are all about.
Then all of a sudden, the client says they need to CRUD addresses independently, so that when creating an Event you can just select its address from a drop down list containing all the addresses that are in the database. So we refactor and bring the Address class back, moving the street, city and state columns from the events table back into the new addresses table.
Next the client demands to see the city and state of the address in addition to its street on the web page corresponding to our view. Now that wrapper method requirement is starting to fire me up.
Because we need this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Event < ActiveRecord::Base belongs_to :address def street address.street end def city address.city end def state address.state end end |
So our view can be written nice and “shy” like this:
1 2 3 |
<%= @event.street %> <%= @event.city %> <%= @event.state %> |
Now Event is just 1 class and Address just 1 other class its associated with, imagine a normal app with several classes and many different associations between them. As you can see, in order to remain “shy” we’re going to have a ton of wrapper methods.
I don’t want to write all those wrapper methods, so I have to be fine with my view looking like this:
1 2 3 |
<%= @event.address.street %> <%= @event.address.city %> <%= @event.address.state %> |
Yes it is not “shy” and it is dependent (coupled) to the implementation of the Event class but I’m going to justify that by saying “views are allowed to rip apart objects”.
Ok. Hear me out here.
So the front of our app is the view i.e. the web page. And the back of our app is the database. Now the database is nothing but state – no behavior, just the results of ripping apart (flattening) an object. What about the web page? It’s always a display of that same state. So I’m saying that the web page is nothing but state and therefore has the same rights as the database in ripping apart an object in order to display it to the user.
Everything between the web page and the database is behavior. And I’d say that your classes should be “shy” but your views have every right not to be because they have to show the object’s state to the user.
So I’d say keep your controllers and models “shy” but let your views run wild!
About this entry
You're reading an entry on GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS, the company weblog of thoughtbot, inc.
- Author:
- Jared Carroll
- Published:
- May 7th 10:54 AM
- Updated:
- September 30th 09:57 AM
- Sections:
- Development
thoughtbot is hiring
We are hiring web developers and web designers in both Boston and New York, NY.
What are we up to?
We built Shoulda, an eclectic set of additions to Test::Unit; Paperclip to manage uploaded files without hassle; factory_girl a replacement for Rails fixtures; Jester, a REST/ActiveResource client written in Javascript, and Squirrel, an enhancement for ActiveRecord's find syntax; — amongst some other projects.

Chad (President) and Jon (CTO) co-authored a technical book titled Pro Active Record: Databases with Ruby and Rails, which explores the ins and outs of the ActiveRecord ruby library. You can buy it today at Amazon.com.
About thoughtbot, inc.
We are a small web application development consulting business, with offices in Boston, MA and New York, NY. If you're looking to find a team for your next web development project or your new web application — get in touch.
7 comments
Jump to comment form