O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

TDC2016POA | Trilha Ruby - Melhorando seu código com Law of Demeter e Tell don't ask

173 visualizações

Publicada em

Melhorando seu código com Law of Demeter e Tell don't ask

Publicada em: Educação
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

TDC2016POA | Trilha Ruby - Melhorando seu código com Law of Demeter e Tell don't ask

  1. 1. MELHORANDO SEU CÓDIGO Law of Demeter Tell, don’t ask
  2. 2. Sobre mim @nelson_senna https://nelsonsar.github.io
  3. 3. DRY? YAGNI? SOLID? TELL DON’T ASK LAW OF DEMETER DDD!
  4. 4. –Alan Kay “The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be.”
  5. 5. class Paperboy attr_reader :wallet def initialize(wallet) @wallet = wallet end def receive_from(customer, amount) if customer.wallet.try(:amount).to_f > amount @wallet.amount = amount customer.wallet = customer.wallet.amount - amount else nil end end end
  6. 6. class Paperboy attr_reader :wallet def initialize(wallet) @wallet = wallet end def receive_from(customer, amount) if customer.wallet.try(:amount).to_f > amount @wallet.amount = amount customer.wallet = customer.wallet.amount - amount else nil end end end
  7. 7. class Paperboy attr_reader :wallet def initialize(wallet) @wallet = wallet end def receive_from(customer, amount) if customer.wallet.try(:amount).to_f > amount @wallet.amount = amount customer.wallet = customer.wallet.amount - amount else nil end end end
  8. 8. –Ruby Science “Referencing another object’s state directly couples two objects together based on what they are, rather than on what they do.”
  9. 9. DE FORMA PRÁTICA
  10. 10. describe Paperboy do describe '#receive_from' do let(:paperboy) { described_class.new(Wallet.new(0)) } context 'when customer has enough money to pay' do it 'add due amount to wallet' do customer = double allow(customer).to receive(:wallet).and_return(Wallet.new(10)) paperboy.receive_from(user, 5) expect(paperboy.wallet.amount).to eq(5) end end end end
  11. 11. describe Paperboy do describe '#receive_from' do let(:paperboy) { described_class.new(Wallet.new(0)) } context 'when customer has enough money to pay' do it 'add due amount to wallet' do customer = double allow(customer).to receive(:wallet).and_return(Wallet.new(10)) paperboy.receive_from(user, 5) expect(paperboy.wallet.amount).to eq(5) end end end end
  12. 12. describe Paperboy do describe '#receive_from' do let(:paperboy) { described_class.new(Wallet.new(0)) } context 'when customer has enough money to pay' do it 'add due amount to wallet' do customer = double allow(customer).to receive(:wallet).and_return(Wallet.new(10)) paperboy.receive_from(user, 5) expect(paperboy.wallet.amount).to eq(5) end end end end
  13. 13. E ISSO TEM UM CHEIRINHO…
  14. 14. –Reek doumentation “Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.”
  15. 15. NÃO SE CONVENCEU?
  16. 16. def associate_user @order ||= current_order if try_spree_current_user && @order if @order.user.blank? || @order.email.blank? @order.associate_user!(try_spree_current_user) end end end
  17. 17. TELL, DON’T ASK
  18. 18. –Martin Fowler “It reminds us that rather than asking an object for data and acting on that data, we should instead tell an object what to do.”
  19. 19. class Order def apply_discount(promotion) if promotion.eligible?(shipment) promotion.activate(shipment) end end end
  20. 20. class Order def apply_discount(promotion) if promotion.eligible?(shipment) promotion.activate(shipment) end end end
  21. 21. LAW OF DEMETER
  22. 22. –Ruby Science “The law restricts how deeply a method can reach into another object’s dependency graph, preventing any one method from becoming tightly coupled to another object’s structure.”
  23. 23. class Paperboy attr_reader :wallet def initialize(wallet) @wallet = wallet end def receive_from(customer, amount) if customer.wallet.try(:amount).to_f > amount @wallet.amount = amount customer.wallet = customer.wallet.amount - amount else nil end end end
  24. 24. class Paperboy attr_reader :wallet def initialize(wallet) @wallet = wallet end def receive_from(customer, amount) self.wallet.add(customer.pay(amount)) end end
  25. 25. NULL OBJECT
  26. 26. –Martin Fowler “Instead of returning null, or some odd value, return a Special Case that has the same interface as what the caller expects.”
  27. 27. def associate_user @order ||= current_order if try_spree_current_user && @order if @order.user.blank? || @order.email.blank? @order.associate_user!(try_spree_current_user) end end end
  28. 28. def try_spree_current_user if respond_to?(:spree_current_user) spree_current_user elsif respond_to?(:current_spree_user) current_spree_user else Guest.new end end
  29. 29. DESVANTAGENS E CUIDADOS
  30. 30. https://github.com/troessner/reek
  31. 31. PRINCÍPIOS DEVERIAM AJUDAR E NÃO CONFUNDIR
  32. 32. DÚVIDAS
  33. 33. REFERÊNCIAS • http://www.dan-manges.com/blog/37 • http://www.virtuouscode.com/2011/06/28/do-or-do-not-there-is-no-try/ • http://gmoeck.github.io/2011/09/28/why-you-should-care-about-information-hiding.html • http://blog.davidchelimsky.net/blog/2006/11/27/fighting-the-urge-to-ask/ • http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf • martinfowler.com/bliki/TellDontAsk.html • https://adamcod.es/2013/11/22/tell-dont-ask.html • https://pragprog.com/articles/tell-dont-ask • https://edelpero.svbtle.com/most-common-mistakes-on-legacy-rails-apps • http://www.mockobjects.com/2006/10/tell-dont-ask-and-mock-objects.html • https://robots.thoughtbot.com/tell-dont-ask • https://skillsmatter.com/skillscasts/8611-tell-dont-ask • https://www.javacodegeeks.com/2015/11/tell-dont-ask.html • http://natpryce.com/articles/000777.html
  34. 34. REFERÊNCIAS • http://martinfowler.com/bliki/GetterEradicator.html • http://verraes.net/2014/09/objects-as-contracts-for-behaviour/ • https://medium.com/skyfishtech/retracing-original-object-oriented- programming-f8b689c4ce50#.yk9k1s7ku • http://brightonruby.com/2016/the-point-of-objects-john-cinnamond/ • https://github.com/spree/spree/blob/master/core/app/models/spree/ promotion_handler/page.rb • https://github.com/troessner/reek/blob/master/docs/Feature- Envy.md

×