Sto leggendo un libro intitolato Rails AntiPatterns e parlano dell'utilizzo della delega per evitare di infrangere la Legge di Demetra. Ecco il loro primo esempio:
Credono che chiamare qualcosa di simile nel controller sia male (e sono d'accordo)
@street = @invoice.customer.address.street
La soluzione proposta è quella di effettuare le seguenti operazioni:
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
Stanno affermando che dato che usi solo un punto, non stai infrangendo la Legge di Demetra qui. Penso che questo non sia corretto, perché stai ancora passando attraverso il cliente per cercare l'indirizzo per ottenere la via della fattura. Ho avuto questa idea principalmente da un post sul blog che ho letto:
http://www.dan-manges.com/blog/37
Nel post del blog l'esempio principale è
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
Il post sul blog afferma che sebbene ci sia solo un punto customer.cash
invece di customer.wallet.cash
, questo codice viola ancora la Legge di Demetra.
Ora nel metodo paperboy collect_money, non abbiamo due punti, ne abbiamo solo uno in "customer.cash". Questa delegazione ha risolto il nostro problema? Affatto. Se osserviamo il comportamento, un ragazzo di carta sta ancora raggiungendo direttamente il portafoglio di un cliente per ottenere incassi.
MODIFICARE
Capisco perfettamente e accetto che questa è ancora una violazione e ho bisogno di creare un metodo Wallet
chiamato prelievo che gestisca il pagamento per me e che dovrei chiamare quel metodo all'interno della Customer
classe. Quello che non capisco è che secondo questo processo, il mio primo esempio viola ancora la Legge di Demetra perché Invoice
sta ancora raggiungendo direttamente Customer
la strada.
Qualcuno può aiutarmi a chiarire la confusione. Ho cercato negli ultimi 2 giorni cercando di far entrare questo argomento, ma è ancora confuso.