2

I am currently learning about delegate and the Law of Demeter. I understand the Law of Demeter, but I can't seem to find a good example of where using delegate to avoid breaking the law would actually even be useful.

I want to find an example related to my project, since I have to give a presentation. The only line of code that I found that could possibly be breaking the Law of Demeter is the following:

@game.promotions.find_by_promo_type("cross")

The model Game has_many Promotions and it is reaching across another model to execute a find call based on promotions attribute promo_type. From my understanding this is a violation of the Law of Demeter, and I should implement the following solution.

class Game < ActiveRecord::Base
   has_many :promotions

   delegate :find_by_promo_type, :to => :promotion
end

Can you give me an example where this would actually be useful besides "the Law of Demeter says so".

The only thing I can think of, is for some reason I wanted to change the name of promotions to promos, then the solution would be useful because I would only need to make the following change and :find_by_promo_type will still work for Game

class Game < ActiveRecord::Base
   has_many :promos

   delegate :find_by_promo_type, :to => :promos
end

The only thing is, I believe this argument is flawed. If I were to change a models name, I would also have to refactor code in many other places that don't even break the Law of Demeter. It's hard to believe that this is all the Law of Demeter can accomplish in regards to this example.

Can somebody please help me understand this.

  • 1
    According to the book im reading 'Rails Antipatterns', breaking the law of demeter is when I am trying to directly access a method/attribute of a model that does not belong to me. Example: I am trying to access find_by_promo_type from the Game model through promotions – user2158382 Oct 16 '13 at 4:59
1

Let's say, for example, you wanted to cache or log that promotion, only when you access it through Game. Having broken the Law of Demeter, you cannot do this easily. You have to find every reference to .promotions.find_by_promo_type and identify the ones that are applied to Games and change them to .find_promotion_by_promo_type before you can add that code.

If you've delegated it in your code then you simply replace that with a full-blown method (and then rename it, if necessary).

That said, the Law of Demeter should really be called the Guideline of Demeter. It's a very good principle to bear in mind but, as you identified, it can add maintenance to common updates, to avoid a major problem if you make a change that you are 99% sure you'll never make.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.