Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
MELHORANDO SEU
CÓDIGO
Law of Demeter
Tell,
don’t ask
Sobre mim
@nelson_senna
https://nelsonsar.github.io
DRY?
YAGNI?
SOLID?
TELL DON’T ASK
LAW OF DEMETER
DDD!
–Alan Kay
“The key in making great and growable
systems is much more to design how its
modules communicate rather than wha...
class Paperboy
attr_reader :wallet
def initialize(wallet)
@wallet = wallet
end
def receive_from(customer, amount)
if custo...
class Paperboy
attr_reader :wallet
def initialize(wallet)
@wallet = wallet
end
def receive_from(customer, amount)
if custo...
class Paperboy
attr_reader :wallet
def initialize(wallet)
@wallet = wallet
end
def receive_from(customer, amount)
if custo...
–Ruby Science
“Referencing another object’s state
directly couples two objects together
based on what they are, rather tha...
DE FORMA PRÁTICA
describe Paperboy do
describe '#receive_from' do
let(:paperboy) { described_class.new(Wallet.new(0)) }
context 'when custo...
describe Paperboy do
describe '#receive_from' do
let(:paperboy) { described_class.new(Wallet.new(0)) }
context 'when custo...
describe Paperboy do
describe '#receive_from' do
let(:paperboy) { described_class.new(Wallet.new(0)) }
context 'when custo...
E ISSO TEM UM
CHEIRINHO…
–Reek doumentation
“Feature Envy occurs when a code fragment
references another object more often than it
references itsel...
NÃO SE CONVENCEU?
def associate_user
@order ||= current_order
if try_spree_current_user && @order
if @order.user.blank? || @order.email.blan...
TELL, DON’T ASK
–Martin Fowler
“It reminds us that rather than asking an
object for data and acting on that data,
we should instead tell a...
class Order
def apply_discount(promotion)
if promotion.eligible?(shipment)
promotion.activate(shipment)
end
end
end
class Order
def apply_discount(promotion)
if promotion.eligible?(shipment)
promotion.activate(shipment)
end
end
end
LAW OF DEMETER
–Ruby Science
“The law restricts how deeply a method
can reach into another object’s dependency
graph, preventing any one ...
class Paperboy
attr_reader :wallet
def initialize(wallet)
@wallet = wallet
end
def receive_from(customer, amount)
if custo...
class Paperboy
attr_reader :wallet
def initialize(wallet)
@wallet = wallet
end
def receive_from(customer, amount)
self.wal...
NULL OBJECT
–Martin Fowler
“Instead of returning null, or some
odd value, return a Special Case that
has the same interface as what th...
def associate_user
@order ||= current_order
if try_spree_current_user && @order
if @order.user.blank? || @order.email.blan...
def try_spree_current_user
if respond_to?(:spree_current_user)
spree_current_user
elsif respond_to?(:current_spree_user)
c...
DESVANTAGENS E
CUIDADOS
https://github.com/troessner/reek
PRINCÍPIOS DEVERIAM
AJUDAR E NÃO
CONFUNDIR
DÚVIDAS
REFERÊNCIAS
• http://www.dan-manges.com/blog/37
• http://www.virtuouscode.com/2011/06/28/do-or-do-not-there-is-no-try/
• h...
REFERÊNCIAS
• http://martinfowler.com/bliki/GetterEradicator.html
• http://verraes.net/2014/09/objects-as-contracts-for-be...
TDC2016POA | Trilha Ruby - Melhorando seu código com Law of Demeter e Tell don't ask
TDC2016POA | Trilha Ruby - Melhorando seu código com Law of Demeter e Tell don't ask
TDC2016POA | Trilha Ruby - Melhorando seu código com Law of Demeter e Tell don't ask
Prochain SlideShare
Chargement dans…5
×

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

171 vues

Publié le

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

Publié dans : Formation
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

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

×