2009-12-28 65 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不是。