Я читаю книгу під назвою Rails AntiPatterns, і вони говорять про використання делегації, щоб уникнути порушення закону про деметер. Ось їх головний приклад:
Вони вважають, що викликати щось подібне в контролері погано (і я згоден)
@street = @invoice.customer.address.street
Запропоноване ними рішення полягає в наступному:
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
Вони заявляють, що оскільки ви використовуєте лише одну крапку, ви тут не порушуєте Закон Деметера. Я думаю, що це неправильно, оскільки ви все ще переживаєте клієнта, щоб пройти адресу, щоб отримати вулицю рахунку-фактури. Я в першу чергу отримав цю ідею з публікації в блозі, яку я прочитав:
http://www.dan-manges.com/blog/37
У публікації щоденника головний приклад
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
У публікації блогу зазначається, що хоча customer.cash
замість нього є лише одна крапка customer.wallet.cash
, цей код все ще порушує закон про деметер.
Зараз у методі Paperboy collection_money у нас немає двох крапок, у нас просто є "customer.cash". Чи вирішила ця делегація нашу проблему? Зовсім ні. Якщо ми подивимось на поведінку, папірець все ще потрапляє безпосередньо у гаманець клієнта, щоб отримати гроші.
EDIT
Я повністю розумію і погоджуюся, що це все-таки порушення, і мені потрібно створити метод у Wallet
call call, який обробляє платіж за мене, і що я повинен викликати цей метод всередині Customer
класу. Чого я не розумію, це те, що згідно з цим процесом, мій перший приклад все ще порушує Закон Деметера, оскільки Invoice
досі досягає прямо, Customer
щоб отримати вулицю.
Хтось може допомогти мені очистити плутанину. Я шукав останні 2 дні, намагаючись дозволити цій темі зануритися, але це все ще заплутано.