Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Love of Demeter

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Love of Demeter

What is Law of Demeter? Should we always respect it? What's the best recipe for a pizza? This presentation answers two of these three questions.

Avatar for nbartlomiej

nbartlomiej

June 25, 2012
Tweet

More Decks by nbartlomiej

Other Decks in Programming

Transcript

  1. 1 class Wallet 2 include Mongoid::Document 3 4 5 6

    7 8 9 10 11 12 13 14 15 16 17 end
  2. 1 class Wallet 2 include Mongoid::Document 3 4 belongs_to :customer

    5 field :cash, type: Integer 6 7 8 9 10 11 12 13 14 15 16 17 end
  3. 1 class Wallet 2 include Mongoid::Document 3 4 belongs_to :customer

    5 field :cash, type: Integer 6 7 def store(amount) 8 update_attribute(:cash, cash + amount) 9 end 10 11 def take(amount) 12 if cash >= amount 13 update_attribute(:cash, cash - amount) 14 end 15 end 16 17 end
  4. 1 class Customer 2 include Mongoid::Document 3 4 has_one :wallet

    5 end 6 7 8 9 class PizzaMan 10 def collect_money(customer, amount) 11 # pending 12 end 13 end 14
  5. 1 class Customer 2 include Mongoid::Document 3 4 has_one :wallet

    5 end 6 7 8 9 class PizzaMan 10 def collect_money(customer, amount) 11 customer.wallet.take(amount) 12 end 13 end 14
  6. 1 class Customer 2 include Mongoid::Document 3 4 has_one :wallet

    5 6 def pay(amount) 7 wallet.take(amount) 8 end 9 end 10 11 12 13 14 15 16
  7. 1 class Customer 2 include Mongoid::Document 3 4 has_one :wallet

    5 6 def pay(amount) 7 wallet.take(amount) 8 end 9 end 10 11 12 class PizzaMan 13 def collect_money(customer, amount) 14 customer.pay(amount) 15 end 16 end
  8. In method, send messages only to: Self. Self method results,

    Self collection elements. Method parameters. Newly created objects.
  9. 1 class PizzaMan 2 @pizzas = [] 3 4 def

    tweet 5 Tweet.new("Tomatoes out, using jalapeños.") 6 end 7 8 def collect_money(customer, amount) 9 10 11 12 13 14 end 15 16 end
  10. 1 class PizzaMan 2 @pizzas = [] 3 4 def

    tweet 5 Tweet.new("Tomatoes out, using jalapeños.") 6 end 7 8 def collect_money(customer, amount) 9 tweet 10 11 12 13 14 end 15 16 end
  11. 1 class PizzaMan 2 @pizzas = [] 3 4 def

    tweet 5 Tweet.new("Tomatoes out, using jalapeños.") 6 end 7 8 def collect_money(customer, amount) 9 10 tweet.send! 11 12 13 14 end 15 16 end
  12. 1 class PizzaMan 2 @pizzas = [] 3 4 def

    tweet 5 Tweet.new("Tomatoes out, using jalapeños.") 6 end 7 8 def collect_money(customer, amount) 9 10 11 @pizzas.first.take_slice 12 13 14 end 15 16 end
  13. 1 class PizzaMan 2 @pizzas = [] 3 4 def

    tweet 5 Tweet.new("Tomatoes out, using jalapeños.") 6 end 7 8 def collect_money(customer, amount) 9 10 11 12 customer.pay(amount) 13 14 end 15 16 end
  14. 1 class PizzaMan 2 @pizzas = [] 3 4 def

    tweet 5 Tweet.new("Tomatoes out, using jalapeños.") 6 end 7 8 def collect_money(customer, amount) 9 10 11 12 13 Pizza.new(:marinara).add(:jalapeno) 14 end 15 16 end
  15. 1 2 3 4 5 6 7 8 9 10

    def collect_money(customer, amount) 11 customer.wallet.take(amount) 12 end 13 14
  16. 1 class Customer 2 include Mongoid::Document 3 4 has_one :wallet

    5 6 delegate :cash, to: :wallet, prefix: true 7 8 def wallet_cash=(amount) 9 wallet.cash = amount 10 wallet.save 11 end 12 end 13 14 15 16 17 18 19 20 21 22
  17. 1 class Customer 2 include Mongoid::Document 3 4 has_one :wallet

    5 6 delegate :cash, to: :wallet, prefix: true 7 8 def wallet_cash=(amount) 9 wallet.cash = amount 10 wallet.save 11 end 12 end 13 14 class PizzaMan 15 def collect_money(customer, amount) 16 if customer.wallet_cash >= amount 17 customer.wallet_cash -= amount 18 else 19 # See you later. 20 end 21 end 22 end
  18. #2 You should not (and cannot) Decouple all the things.

    source: http://hyperboleandahalf.blogspot.com/ 2010/06/this-is-why-ill-never-be-adult.html
  19. #2

  20. 1 def chains 2 order.customer.profile.location.country = "PL" 3 end 4

    5 def temp_variables 6 customer = customer.order 7 profile = customer.profile 8 location = profile.location 9 location.country = "PL" 10 end
  21. 1 def chains 2 order.customer.profile.location.country = "PL" 3 end 4

    5 def temp_variables 6 customer = customer.order 7 profile = customer.profile 8 location = profile.location 9 location.country = "PL" 10 end Refactor.
  22. 1 <div> 2 <%= customer.profile.avatar %> 3 <%= customer.profile.country %>

    4 <%= customer.profile.address %> 5 <%= customer.profile.phone %> 6 </div>
  23. 1 <div> 2 <%= customer.profile.avatar %> 3 <%= customer.profile.country %>

    4 <%= customer.profile.address %> 5 <%= customer.profile.phone %> 6 </div> Delegating? Partial?
  24. 1 class PizzaMan 2 def collect_money(customer, amount) 3 if customer.pays_with_credit_card?

    4 collect_from_credit_card(customer.credit_card, amount) 5 else 6 collect_cash(customer, amount) 7 end 8 end 9 10 def collect_cash(customer, amount) 11 # ... 12 end 13 14 def collect_from_credit_card(credit_card, amount) 15 # ... 16 end 17 end
  25. 1 class PizzaMan 2 def collect_money(customer, amount) 3 if customer.pays_with_credit_card?

    4 collect_from_credit_card(customer.credit_card, amount) 5 else 6 collect_cash(customer, amount) 7 end 8 end 9 10 def collect_cash(customer, amount) 11 # ... 12 end 13 14 def collect_from_credit_card(credit_card, amount) 15 # ... 16 end 17 end Use Structural Dependency?