Я читаю книгу под названием 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 collect_money у нас нет двух точек, у нас есть только одна в «customer.cash». Эта делегация решила нашу проблему? Не за что. Если мы посмотрим на поведение, разносчик газет все еще лезет прямо в кошелек клиента, чтобы получить наличные.
РЕДАКТИРОВАТЬ
Я полностью понимаю и согласен с тем, что это все еще является нарушением, и мне нужно создать метод в Wallet
вызываемом выводе, который обрабатывает платеж для меня, и что я должен вызвать этот метод внутри Customer
класса. Что я не понимаю, так это то, что в соответствии с этим процессом мой первый пример все еще нарушает Закон Деметры, потому что Invoice
он все еще идет прямо Customer
к улице.
Может кто-нибудь помочь мне устранить путаницу. Я искал последние 2 дня, пытаясь раскрыть эту тему, но это все еще сбивает с толку.