2012-07-31 56 views
2

我對如何通過一對多協會避免Demeter違法行爲感到困惑。比方說,我有一個模型是這樣的:Demeter與一對多協會的法律

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 } 

這似乎是違反了德米特法,雖然它不是很明顯看到。您仍在展示員工內部結構的知識。避免這種違規行爲的最佳方法是什麼?

回答

2

得墨忒耳定律的目的是爲了避免暴露內部狀態和使用鼓勵一個「說不清,不問」的原則,而不是a.something.do_something,使用a.do_something(然後可以委託其內部成員something)。

即便如此,這並不是一條堅強而快速的規則,永遠不可違反。在這種情況下,沒有真正的解決方法,因爲您不要求員工使用名字做某件事,而只是查詢其名字。

1

嗯。這是我的觀點:

  • ,如果你在一個視圖中同時使用你的例子,我會說上面這兩個例子都OK,因爲,如果你正在創建從多個模型,這是相當顯示信息的視圖我認爲普通,那爲什麼不呢?很明顯,rails中的視圖對數據結構/模型有很多瞭解。在第二個例子中,如果你對一個元素進行迭代(也就是執行一些邏輯),我會考慮把它放到另一個類中,即那種情況下的僱員。但是,如果上面提到的是它的觀點,我寧願不要,特別是如果這意味着從模型方法生成HTML代碼。在我看來,軌道模型比Rob Martin在Clean Code中的Data/Object Anti-Symmetry(P. 95,就在demeter定律之前;-))所描述的對象更像是一個數據結構)

0

得墨忒耳的動機是封裝,而不是「減少點數」。

這對於在域對象中隱藏行爲是最有意義的,但對於在視圖中顯示數據並不那麼重要 - 這不是一個永遠不會破壞的規則。

這篇文章對這個問題的一個很好的解釋:Law of Demeter and Dot Counting