私は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日間探してきましたが、それでも混乱を招きます。