Ich lese ein Buch mit dem Titel Rails AntiPatterns und sie sprechen über die Verwendung von Delegationen, um das Gesetz von Demeter nicht zu brechen. Hier ist ihr Paradebeispiel:
Sie glauben, dass es schlecht ist, so etwas im Controller aufzurufen (und ich stimme zu)
@street = @invoice.customer.address.street
Ihre vorgeschlagene Lösung besteht darin, Folgendes zu tun:
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
Sie behaupten, dass Sie hier nicht gegen das Gesetz von Demeter verstoßen, da Sie nur einen Punkt verwenden. Ich denke, das ist falsch, weil Sie immer noch durch Kunden gehen, um die Adresse durchzugehen, um die Straße der Rechnung zu erhalten. Diese Idee kam mir vor allem in einem Blogbeitrag, den ich las:
http://www.dan-manges.com/blog/37
Im Blogpost ist das Paradebeispiel
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
Der Blogbeitrag besagt, dass dieser Code , obwohl es nur einen Punkt customer.cash
stattdessen gibt customer.wallet.cash
, immer noch gegen das Gesetz von Demeter verstößt.
Jetzt haben wir in der Paperboy-Methode collect_money nicht zwei Punkte, sondern nur einen in "customer.cash". Hat diese Delegation unser Problem gelöst? Überhaupt nicht. Wenn wir uns das Verhalten ansehen, greift ein Zeitungsjunge immer noch direkt in die Brieftasche eines Kunden, um Bargeld herauszuholen.
BEARBEITEN
Ich verstehe und bin damit einverstanden, dass dies immer noch ein Verstoß ist und ich muss eine Methode Wallet
namens "Zurückziehen" erstellen , die die Zahlung für mich abwickelt und die ich innerhalb der Customer
Klasse aufrufen sollte . Was ich nicht verstehe, ist, dass nach diesem Verfahren mein erstes Beispiel immer noch gegen das Gesetz von Demeter verstößt, weil Invoice
es immer noch direkt hineinreicht Customer
, um auf die Straße zu gelangen.
Kann mir jemand helfen, die Verwirrung zu beseitigen? Ich habe in den letzten zwei Tagen nach Informationen gesucht, um dieses Thema aufzugreifen, aber es ist immer noch verwirrend.