Je lis un livre intitulé Rails AntiPatterns et ils parlent d'utiliser la délégation pour éviter d'enfreindre la loi de Demeter. Voici leur premier exemple:
Ils croient qu'appeler quelque chose comme ça dans le contrôleur est mauvais (et je suis d'accord)
@street = @invoice.customer.address.street
La solution proposée consiste à procéder comme suit:
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
Ils affirment que puisque vous n'utilisez qu'un seul point, vous n'enfreignez pas la loi de Déméter ici. Je pense que c'est incorrect, car vous passez toujours par le client pour passer par l'adresse pour obtenir la rue de la facture. J'ai principalement eu cette idée dans un article de blog que j'ai lu:
http://www.dan-manges.com/blog/37
Dans le billet de blog, le premier exemple est
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
Le blog indique que bien qu'il n'y ait qu'un seul point customer.cash
au lieu de customer.wallet.cash
, ce code viole toujours la loi de Demeter.
Maintenant, dans la méthode Paperboy collect_money, nous n'avons pas deux points, nous en avons juste un dans "customer.cash". Cette délégation a-t-elle résolu notre problème? Pas du tout. Si nous examinons le comportement, un paperboy atteint toujours directement le portefeuille d'un client pour retirer de l'argent.
ÉDITER
Je comprends parfaitement et je suis d'accord que c'est toujours une violation et je dois créer une méthode Wallet
appelée appelée qui gère le paiement pour moi et que je devrais appeler cette méthode à l'intérieur de la Customer
classe. Ce que je ne comprends pas, c'est que selon ce processus, mon premier exemple viole toujours la loi de Déméter, car il cherche Invoice
toujours directement Customer
à obtenir la rue.
Quelqu'un peut-il m'aider à dissiper la confusion? Je cherchais depuis 2 jours à essayer de laisser ce sujet pénétrer, mais c'est toujours déroutant.