Thursday, December 20, 2012

Interfaces & Roles in Ruby

The foundation of an object oriented system is the messages.  You don't send messages because you have objects, you have objects because you send messages -- from @sandimetz's book 

Your system is like a teaming pool of objects, all jumping up and down eagerly awaiting a message.

Worlds largest busiest swimming pool - Funckr

Think "Roles"

Initially, it's easy to follow code which depends on concrete classes for collaboration -- that is, instantiating an object, and  expecting it (obviously) to be only that kind of class.  However, the problem is you can't substitute the collaborator for another object that is playing the same role.

Think of it this way: The world is too big!

If you take on the personality of an object, and stand inside it -- then you can limit perspective to the number of things you can deal with at one time.

You are looking out from within an object - a message sender.  You know what you want, but you don't care how your collaborators do it.  You know what you expect from your collaborators.

So, limiting your perspective in this way, you start to see other objects you collaborate with as playing roles -- not specific classes, but a more abstract interface.  A collaborator playing a role could be any number of future object types.
"No object in your system should have to know the class of any other object in order to know how to behave.  Everything is a Duck.  Tell the Duck WHAT and the Duck should know HOW."

Roles are Interfaces

Classes have expectations about the messages their collaborators understand.  You should expect an interface and not a specific class -- think "Role".  Interfaces are just a subset of messages you respond to!

But... how to share with your team? to newcomers?  It's not obvious since we don't have an "Interface" language construct.

The answer is to document roles via tests:
  • For example, a mock with the subset of methods that represent the role (or Interface)
  • A shared spec  to ensure both the mock, and the real objects playing the role conform to the interface
(Note: this post was written directly from notes I made about  the chat between Avdi Grimm and Sandi Metz in "Objects on Rails" deluxe version... go buy it)


Daniel O'Connor said...

Hey Adam,
I'm trying to aggregate the Adelaide Ruby/Rails bloggers around the place.

Would you have any objection to your rss feed being syndicated on ?

So far it's mostly my content ( said...

I believe it's because Ruby is dynamically typed whereas other languages are statically typed. The only reason you'd need to use an interface in PHP is when you use type hinting when passing objects around.