2009-12-28 42 views
7

我一直在使用Rails超過4年,所以很明顯,我喜歡Rails和喜歡做的事情Rails的方式,有時我在不知不覺中下降到黑暗的一面。我們是否將Rails ActiveRecord用作混合結構,即數據結構+對象?

我最近Bob大叔拿起清潔守則。我在第6章,對於我們作爲Rails開發者是否打破了OO設計的基本規則,即Demeter Law還是封裝,有點困惑?德米特定律指出一個對象不應該知道另一個對象的內部,它不應該在方法返回的對象上調用方法,因爲當你這樣做時,它表明一個對象知道太多關於另一個對象的方法。

但很多時候,我們呼籲從模型的另一個對象的方法。例如,當我們有一個像'一個訂單屬於一個用戶'的關係。然後,我們經常結束做order.user.name或者爲了防止它看起來像列車殘骸,我們建立了一個委託來執行order.name。

  1. 這不就像打破德米特法或封裝?

  2. 的另一個問題是:是的ActiveRecord只是一個數據結構或數據傳輸對象與數據庫的接口?

  3. 如果是的話,那麼就不要我們創建了一個混合結構,即半目標和半結構數據通過把我們的業務規則中的ActiveRecord模型?

+1

永遠不要把書看得太重。當然除了「代碼完成」。 – vava 2009-12-28 08:46:14

+1

這樣的「規則」和「法律」只是使代碼變得乾淨的建議。當它更加乾淨時,就去做吧。 – luikore 2009-12-28 09:21:00

+0

我可以肯定地故意違反規則,如果我知道這違反不會導致長期的設計問題,尤其是如果有一種方法可以實現更清晰的代碼沒有違反任何規則,那麼這將是最好的路徑: ) – nas 2009-12-28 09:30:25

回答

15

Rails是Rails的。還有什麼可說的。是的,Rails中的一些成語違反了良好的設計原則。但是我們容忍這個,因爲這是Rails的方式。

說了這麼多,有遠在大多數Rails應用太多型號用途。我經常看到視圖代碼直接訪問模型。我看到業務規則摺疊到活動記錄對象中。更好的方法是將業務規則與活動記錄隔離開來,並將視圖與模型隔離。這不會違反任何欄杆習語,並且會使欄杆應用變得更加靈活和可維護。

+1

在2000系統中引入更多的對象會真的值得嗎?我同意10k +系統,但小規模的系統? – 2009-12-29 05:56:42

+0

如果這樣可以讓設計變得更清晰和更容易擴展,那麼我認爲應該考慮這一點,因爲我已經看到200多個模型的軌道應用程序和一些模型超過1000行。現在可以說這是因爲糟糕的設計。可能有很多原因,但其中一個可能不遵循或違反基本原則。這只是一個想法。 – nas 2009-12-29 13:10:21

+0

恕我直言,叔叔鮑勃上面說過的「更好的方法是將業務規則與活動記錄隔離開,並將這些視圖與模型隔離開來。」說得通。問題是,如果有命令或用戶ActiveRecord對象並且需要一些業務規則,那該如何幹淨地完成呢? – nas 2009-12-29 13:29:03

7

恕我直言,如果按照純粹的方式太多,那麼你在Java等混亂結束了它使用了所有正確的設計模式,但沒有人能記得八行的代碼,你只需要打開一個文件並閱讀其內容。

Rails的ActiveRecord框架是Martin Fowler的Active Record design pattern的實現。在Rails的活動記錄肯定不只是愚蠢的數據結構或DTO的,因爲他們的行爲:他們執行驗證,他們可以告訴你,如果它們的屬性已經改變等等,你是自由的,事實上encouraged,在那裏添加自己的業務邏輯。

滑軌一般鼓勵好的做法如MVC和句法醋,讓糟糕的事情變得困難和/或醜陋。

+0

Rails的肯定鼓勵的良好做法,正如你所提到的基本前提是MVC,瘦控制器和脂肪的模式,一個等等。然而,關於你的答案的第一部分,我不知道是否有人能在一個爛攤子真的結束了通過遵循任何特定語言的正確模式,儘管通過盲目應用不適合於給定問題的設計模式,人們肯定會在任何語言(包括紅寶石)中造成混亂。 – nas 2009-12-29 00:30:56

+0

在Java情況下,這是一團糟,因爲它會影響生產力。使用Rails完成任務非常簡單。 – 2009-12-29 10:15:30

+0

的確如此,我完全同意! 但是,如果你有一個小的rails應用程序,並且如果你不遵循好的設計原則,那麼它可能並不重要。雖然當應用程序增長到一定的水平之上,並且你不加思索地添加代碼,那麼它可能會變得與任何其他語言編寫的代碼一樣混亂。特別是當你看到火車殘骸(order.user.name.split(''))和模型對象直接從視圖訪問。維護現有代碼並添加新功能成爲一場噩夢。 – nas 2009-12-29 13:20:55

1

關於「得墨忒耳定律」有一件事我從來沒見過一提的是距離的概念。我的意思是,「涉及的對象有多密切相關?」我認爲這是否會影響我是否遵循「德米特法」。

在ActiveRecord的的情況下,參與的大部分的LoD侵犯的目的不可分離結合在一起成爲密切的關係。更改這些對象的內部數據結構需要更改數據庫以反映新結構。數據庫的表通常「綁定」在一個單一的數據庫中,甚至通過外鍵約束(或至少包含主外鍵)反映這些「關聯」。

所以我不關心一般自己和我的AR對象之間以下毀滅之王。我知道,由於它們的性質,它們彼此緊密相連。

在另一方面我會更遠處的物體之間更關心的LoD,尤其是那些跨越MVC的邊界或任何其它這樣的設計裝置。

4

是,ActiveRecord的故意破壞封裝。這不是Rails的限制,因爲它是基於它的模式的限制。馬丁·福勒,他的ActiveRecord的定義是非常使用的模板Rails的,說在POEAA ActiveRecord的章節之多:

活動 記錄另一種說法是事實,這夫妻 對象設計數據庫 設計。這使 更難以重構任一設計,因爲項目 前進。

這是來自其他框架的Rails的common criticism。福勒自己說的ActiveRecord主要是使用

...因爲這是不是太複雜 ......如果你的業務邏輯是 複雜,你很快就會想用你的 對象的直接域邏輯關係, 集合,繼承等等。 這些不能輕鬆映射到活動記錄。

福勒接着說,對於與不分離各層一個更好的工作,是優選的復域邏輯Data Mapper pattern,更嚴重的應用程序。這是Rails upcoming move to Merb被普遍認爲是Rails的一個積極舉動的原因之一,因爲除了ActiveRecord之外,Merb還使用DataMapper模式。

我不知道得墨忒耳是ActiveRecord的首要關注的問題。相反,我認爲打破數據和域層之間的封裝打破了鮑勃叔叔的Single Responsibility Principle。我認爲德米特更多的是如何遵循開放/封閉原則的具體例子。但我認爲所有這些背後的更廣泛的想法是相同的:類應該做一件事,並且對未來的變化有強大的作用,這在一定程度上ActiveRecord不是。