14

在 OOD 中,据说对象的设计以其身份和行为为特征。

在我看来,过去使用过 ORM 的主要目的是围绕存储/检索数据的能力。也就是说,ORM对象不是按行为设计的,而是数据(即数据库表)。案例和要点:许多 ORM 工具都带有指向数据库表和点击对象生成器。

如果对象不再以行为为特征,在我看来,这将混淆对象的身份和责任。随后,如果对象不是由职责定义的,这可能会导致紧密耦合的类和整体糟糕的设计。

此外,我认为在应用程序设置中,您将面临可伸缩性问题。

所以,我的问题是,你认为 ORM 对 OO 设计会适得其反吗?也许潜在的问题是它们是否对应用程序开发产生反作用。

4

9 回答 9

10

良好的数据库设计要求与良好的 OO 设计要求之间存在众所周知且经常被忽视的阻抗失配。大多数开发人员(根据我的经验)要么不理解这种阻抗不匹配,要么不在乎。由于从数据库开始并从中生成对象(而不是相反)更为常见,所以是的,您最终会得到作为持久层很好但从 OO 角度来看不是最佳的对象。(反过来,从对象模型生成数据库,让我想瞪大眼睛。)

Why are they sub-optimal from an OO perspective? Because the objects produced by an ORM are not business objects, even with partial classes and the like. Business objects model behavior. ORM objects model persistence. I'm not going to spend ten paragraphs arguing this distinction. It's something Rocky Lhotka has covered quite well in his books on Business Objects and his CSLA framework. Whether or not you like or use CSLA, I think his arguments are solid ones.

于 2010-04-13T11:24:28.113 回答
4

如果对象不再以行为为特征,在我看来,这将混淆对象的身份和责任。

有问题的对象确实具有作为定义行为的数据库读取和写入。他们只是没有太多其他的东西。

实际情况非常简单:面向对象本身并不是目的,它是达到目的的一种手段——但在某些情况下,它对改善最终结果并没有多大帮助。ORM 的许多用途就是一个很好的例子——它们是 CRUD 应用程序的数千种变体,它们不需要或不想将任何实际行为附加到它们处理的大多数数据上。

通过将大量(如果有的话)数据“行为”编码到应用程序本身的代码中,应用程序作为一个整体获得了灵活性。相反,他们通常最好将其作为“哑”数据,它们只是从 UI 传递到数据库,然后返回到报告等。稍加注意,当您尝试将数据视为具有真实行为的真实对象并正确编码到应用程序中时,这可以实现几乎不可能匹配的大量用户自定义。

当然,这还有另一面:它会使确保数据的完整性或仅适当使用数据变得更加困难——我见过在计算中意外使用错误字段的代码,所以他们平均办公室数量而不是办公室面积(以平方英尺为单位)。两者都是用户定义的字段,只是说内容应该是数字。应用程序无法知道其中一个完全合理,而另一个则完全没有。

于 2010-04-12T21:21:24.500 回答
3

案例和要点:许多 OR/M 工具都带有指向数据库表和单击对象生成器。

是的,但是有相同的,如果不是更大的数字或 ORM 解决方案,它们基于您的对象并生成您的数据库表。

如果您从数据开始,然后强制自动生成的对象具有对象行为,是的,您可能会感到困惑......但是如果您从对象开始并生成数据库作为辅助层,那么您最终会得到一些东西更有用,即使数据库可能没有尽可能优化。

如果您正在寻找不使用 ORM 的借口,请不要使用它。我个人发现它为我节省了数千行代码来做一些琐碎的事情,而 ORM 做得很好。

于 2010-04-12T20:23:33.007 回答
2

我不相信 ORM 对 OO 设计会适得其反,除非您想坚持认为持久性是行为的一个组成部分。

我会将持久性与业务行为分开。您当然可以自由地将业务行为添加到 ORM 为您生成的任何对象。

于 2010-04-12T20:21:42.677 回答
2

我还看到了倾向于从 OO 模型生成数据库的 ORM 系统。

如果有的话,我想说 ORM 更倾向于生成好的 OO 代码,而不是生成好的数据库代码。

理想情况下,一个成功的 ORM 连接了这两个世界,从业务领域问题解决和实现的角度来看,您的应用程序代码会很棒,而从规范化、性能和 ETL/报告/复制的角度来看,您的数据库代码和模型会很棒。

于 2010-04-12T20:26:10.833 回答
2

在将数据与行为分开的系统上,这绝对会适得其反。

Orm 系统倾向于分析现有的数据库表以用您的语言创建愚蠢的“对象”。这些东西不是真正的对象,因为它们不包含业务行为,但是由于人们具有这些结构,因此他们倾向于使用它们。

Ruby on Rails (Active Record) 实际上将您的数据绑定到“实时”类——这要好得多。

我从来没有见过我真正喜欢的系统——ActiveRecord 很接近,但它做出了一些我不太满意的 rubiesque 假设——最大的是默认提供公共 setter 和 getter。

但总而言之——我见过很多优秀的 OO 程序员因为 ORM 而写出了糟糕的代码。

于 2010-04-12T20:32:03.667 回答
1

与大多数此类问题一样,这取决于您的使用情况。

ORM工具的主要使用方式有:

  1. 按数据定义对象,在整个应用程序代码中使用此对象(BAD BAD BAD)
  2. 仅将 ORM 对象用于数据访问,定义您自己的对象,并在它们之间定义一个解释层(更好)

如果从头开始,第三种方法是从您的对象模型中设计数据。(如果可能最好)

所以是的,如果您通过数据表定义对象并在整个代码中使用它,您将不会使用 OOD 并引入非常糟糕的设计和维护问题。

但是,如果您只使用 ORM 对象作为数据访问工具(替换 ADO),那么您可以自由地将好的 OOD 和 ORM 一起使用。当然,构建解释层需要更多代码,但可以实现更好的实践,所需的代码并不比旧的 ADO 代码多。

于 2010-04-12T20:28:23.217 回答
0

我从 C# 的角度回答这个问题,因为这是我进行大部分开发的地方......

我明白你的意思,但我认为通过创建部分类的能力,你仍然可以创建具有你喜欢的任何行为的对象,并且仍然可以获得 OR/M 为表带来的数据检索功能。

于 2010-04-12T20:19:48.353 回答
0

从我所看到的 ORM 来看,它们并不违反 OO 原则——实际上与它们完全正交。(供参考 - ORM 技术非常新,Java 视角)

我的理由是 ORM 可以帮助您将类的数据成员存储到持久存储中,而无需耦合到该存储并自己编写代码。您仍然可以决定数据成员并编写类的行为。

我猜你可能会滥用 ORM 来破坏 OO 原则,但是你可以用任何东西来做到这一点。您可以使用工具从预先存在的表中创建骨架数据类,但您仍会创建方法等。

于 2010-04-12T20:22:19.360 回答