2

1対多の関連付けでデメテルの法則違反を回避する方法について混乱しています。次のようなモデルがあるとします。

class Organization < ActiveRecord::Base
  has_one :address
  has_many :employees
end

これを行うのはデメテルの法則に違反すると思います。

organization.address.street_name

これは、*address_street_name* メソッドを使用することで回避できます。それは十分に簡単な解決策です。しかし、今これを行うとしましょう:

organization.employees.each { |employee| puts employee.first_name }

これはデメテルの法則に違反しているように見えますが、それほど明白ではありません。あなたはまだ従業員の内部構造に関する知識を示しています。この種の違反を回避する最善の方法は何ですか?

4

3 に答える 3

2

デメテルの法則の目標は、内部状態の公開を避けることであり、 を使用するのではなく、「教えて、聞かないで」の原則を使用することを奨励することですa.something.do_something(a.do_somethingその後、その内部メンバーに委譲することができますsomething)。

そうは言っても、絶対に違反できない厳格なルールではありません。この場合、従業員にファーストネームで何かをするように頼んでいるのではなく、ファーストネームを照会しているだけなので、これを回避する実際の方法はありません。

于 2012-07-31T23:55:03.017 に答える
1

うーん。これが私の意見です:

  • ビューで両方の例を使用する場合、上記の両方の例で問題ないと思います。複数のモデルからの情報を表示するビューを作成している場合、これは非常に一般的だと思います。レールのビューがデータ構造/モデルについて多くのことを知っていることも明らかです。

  • 2 番目の例では、要素を反復処理する (つまり、何らかのロジックを実行する) 場合、それを他のクラス (この場合は employees) に入れることを検討します。しかし、繰り返しになりますが、それがビュー内にある場合、特にそれがモデル メソッドから html コードを生成することを意味する場合は、そうしません。私の意見では、Rails モデルはオブジェクトというよりもデータ構造に近いものであり、Rob Martin が Clean Code の Data/Object Anti-Symmetry セクションで説明しているように (P. 95、demeter の法則の直前 ;-))

于 2012-07-31T23:54:05.187 に答える
0

デメテルの法則の動機はカプセル化であり、「ドット カウントを減らす」ことではありません。

ドメイン オブジェクトの動作を非表示にすることは最も理にかなっていますが、ビューにデータを表示することにはあまり意味がありません。決して破ってはならないルールではありません。

この記事は、その主題について本当に良い説明を提供します:Demeter and Dot Countingの法則

于 2012-08-01T00:05:18.640 に答える