私は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
ドットを1つしか使用しないため、ここでデメテルの法則に違反していないと述べています。あなたはまだ顧客を通り抜けて住所を通り、請求書の番地を取得しているので、これは間違っていると思います。私は主に私が読んだブログ投稿からこのアイデアを得ました:
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
代わりにドットは1つしかありませんがcustomer.wallet.cash
、このコードは依然としてデメテルの法則に違反していると述べています。
Paperboyのcollect_moneyメソッドでは、2つのドットはありません。「customer.cash」に1つのドットがあります。この委任は問題を解決しましたか?どういたしまして。振る舞いを見ると、ペーパーボーイはまだ顧客の財布に直接手を差し伸べて現金を引き出しています。
編集
これはまだ違反でありWallet
、支払いを処理するwithdrawというメソッドを作成する必要があり、Customer
クラス内でそのメソッドを呼び出す必要があることを完全に理解し、同意します。私が得ていないのは、このプロセスによれば、私の最初の例Invoice
はまだ通りに到達するために直接Customer
手を伸ばしているため、デメテルの法則に違反しているということです。
誰かが私が混乱を解消するのを手伝ってもらえますか。私はこのトピックを沈めようとして過去2日間探してきましたが、それでも混乱を招きます。