Czytam książkę zatytułowaną Rails AntiPatterns, a oni mówią o korzystaniu z delegacji, aby uniknąć łamania Prawa Demeter. Oto ich najlepszy przykład:
Uważają, że wywołanie czegoś takiego w kontrolerze jest złe (i zgadzam się)
@street = @invoice.customer.address.street
Ich proponowanym rozwiązaniem jest wykonanie następujących czynności:
class Customer
has_one :address
belongs_to :invoice
def street
address.street
end
end
class Invoice
has_one :customer
def customer_street
customer.street
end
end
@street = @invoice.customer_street
Mówią, że skoro używasz tylko jednej kropki, nie łamiesz tutaj Prawa Demetera. Myślę, że jest to niepoprawne, ponieważ nadal przechodzisz przez klienta, aby przejść przez adres, aby uzyskać ulicę z fakturą. Ten pomysł pochodzi przede wszystkim z postu na blogu, który przeczytałem:
http://www.dan-manges.com/blog/37
W poście na blogu najlepszym przykładem jest
class Wallet
attr_accessor :cash
end
class Customer
has_one :wallet
# attribute delegation
def cash
@wallet.cash
end
end
class Paperboy
def collect_money(customer, due_amount)
if customer.cash < due_ammount
raise InsufficientFundsError
else
customer.cash -= due_amount
@collected_amount += due_amount
end
end
end
Stany wpis na blogu, że chociaż istnieje tylko jedna kropka customer.cash
zamiast customer.wallet.cash
tego kodu nadal narusza Prawo Demeter.
Teraz w metodzie Paperboy Collect_money nie mamy dwóch kropek, mamy tylko jedną w „customer.cash”. Czy ta delegacja rozwiązała nasz problem? Ani trochę. Jeśli spojrzymy na to zachowanie, gazeciarz wciąż sięga bezpośrednio do portfela klienta, aby uzyskać gotówkę.
EDYTOWAĆ
W pełni rozumiem i zgadzam się, że to nadal stanowi naruszenie i muszę stworzyć metodę Wallet
zwaną wypłatą, która obsłuży dla mnie płatność i że powinienem wywołać tę metodę w Customer
klasie. Nie rozumiem, że zgodnie z tym procesem mój pierwszy przykład wciąż narusza Prawo Demetera, ponieważ Invoice
wciąż sięga bezpośrednio Customer
po ulicę.
Czy ktoś może mi pomóc usunąć zamieszanie. Przez ostatnie 2 dni szukałem sposobu, aby ten temat zagłębił się, ale nadal jest mylący.