Top Banner
MELHORANDO SEU CÓDIGO Law of Demeter Tell, don’t ask
37

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

Jan 09, 2017

Download

Technology

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Melhorando seu código com Law of Demeter e Tell don't ask

MELHORANDO SEU CÓDIGO

Law of Demeter

Tell,

don’t ask

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

Sobre mim@nelson_senna

https://nelsonsar.github.io

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

DRY?

YAGNI?SOLID?

TELL DON’T ASK

LAW OF DEMETERDDD!

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

–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.”

Page 5: Melhorando seu código com Law of Demeter e Tell don't ask
Page 6: Melhorando seu código com Law of Demeter e Tell don't ask

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

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

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

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

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

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

–Ruby Science

“Referencing another object’s state directly couples two objects together

based on what they are, rather than on what they do.”

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

DE FORMA PRÁTICA

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

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

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

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

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

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

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

E ISSO TEM UM CHEIRINHO…

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

–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.”

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

NÃO SE CONVENCEU?

Page 17: Melhorando seu código com Law of Demeter e Tell don't ask
Page 18: Melhorando seu código com Law of Demeter e Tell don't ask

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

Page 19: Melhorando seu código com Law of Demeter e Tell don't ask
Page 20: Melhorando seu código com Law of Demeter e Tell don't ask

TELL, DON’T ASK

Page 21: Melhorando seu código com Law of Demeter e 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 an object what

to do.”

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

class Order def apply_discount(promotion) if promotion.eligible?(shipment) promotion.activate(shipment) end end end

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

class Order def apply_discount(promotion) if promotion.eligible?(shipment) promotion.activate(shipment) end end end

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

LAW OF DEMETER

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

–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.”

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

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

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

class Paperboy attr_reader :wallet

def initialize(wallet) @wallet = wallet end

def receive_from(customer, amount) self.wallet.add(customer.pay(amount)) end end

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

NULL OBJECT

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

–Martin Fowler

“Instead of returning null, or some odd value, return a Special Case that has the same interface as what the

caller expects.”

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

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

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

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

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

DESVANTAGENS E CUIDADOS

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

https://github.com/troessner/reek

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

PRINCÍPIOS DEVERIAM AJUDAR E NÃO

CONFUNDIR

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

DÚVIDAS

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

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

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

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