How To Implement Law Of Demeter In Ruby

By Sarbada Nanda Jaiswal on Aug, 11, 2016

Most of the developers who are digging deeper into proper way to build software might have had problem in understanding the law of demeter in first go. Here is our attempt to simplify this for the new generation of developers.

You can read the formal definitions here :

C2wiki: http://c2.com/cgi/wiki/LawOfDemeter?LawOfDemeter

Wikipedia: https://en.wikipedia.org/wiki/Law_of_Demeter

The law of demeter fundamentally describes following things:

Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.

Each unit should only talk to its friends; don't talk to strangers.

Only talk to your immediate friends.

In our context as programmers, an object should avoid calling on methods of a member object returned by another method. For many modern object oriented languages that use a dot as field identifier, the law can be stated simply as “use only one dot”. That is, the code a.b.Method() breaks the law where a.Method() does not.

Ruby on Rails Bad smell code:

class Project < ActiveRecord::Base

belongs_to :user

end project.user.name

project.user.address

project.user.cellphone

These lines break law of demeter. To solve this we should use methods like as:

project.user_name

project.user_address

Project.user_cellphone

Now, this follows the law of demeter. But if we use methods for each field then we need to add bunch of methods in the model.

class Project < ActiveRecord::Base

belongs_to :user

def user_name

user.name

end

def user_address

user.address

end

def user_cellphone

user.cellphone

end

end

class User < ActiveRecord::Base

has_many :projects

end



To remove above bad smell Rails provides a helper method delegate which utilizes the DSL way to generates the wrapper methods. This is the best practice.

delegate:

The concept of delegation is to take some methods and send them off to another object to be processed.

Options:

:to - Specifies the target object

:prefix - Prefixes the new method with the target name or a custom prefix

:allow_nil - if set to true, prevents a NoMethodError to be raised

class Project < ActiveRecord::Base

belongs_to :user

delegate :name, :address, :cellphone, to: :user, prefix: true, allow_nil: true

end

class User < ActiveRecord::Base

has_many :projects

end project.user_name project.user_address

This is how the method can now be accessed with delegate enabled.

Now, we do not break the law of demeter. Due to addition of allow_nil if the project does not have any user then we will just get nil when calling name and no exception!

Now we know what the law of demeter is . But why use it ?. Most of the blog posts out there does not answer this specific question. What are the benefits or advantages of implementing law of demeter in our ruby softwares?.

In general , Law of demeter is an example of loose coupling which states that one component should not heavily rely on other components for getting the job done.

Not when we decrease this coupling. Things are much much easier to change.

But what about the famous method chaining we are used to ?

But If we followed it all the time we could never do method chaining

Method chains are what makes ruby well ruby ! As an example, here’s a method which takes a string and generates a “slug” for generating a friendly url:

def slug(string) string.strip.downcase.tr_s('^[a-z0-9]', '-‘) end

That’s three levels of method call chaining. That does not follow the Law of Demeter. But the law never says anything about the number of methods called, or the number of objects a method uses. It is strictly concerned with the number of types a method deals with.

The #slug method expects a String, and calls three methods, each one returning… another String. In fact, because it only calls methods for the type of object (String) passed into it as parameters, we can conclude that it follows the Law of Demeter.

References and Bibliography

http://rails-bestpractices.com/posts/2010/07/24/the-law-of-demeter/

http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx/

http://www.virtuouscode.com/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/

Share This: