45

持久性无知通常被定义为持久化和检索标准 .NET 对象(或 POCO,如果你真的坚持给它们命名)的能力。标准 .NET 对象的一个​​看似广为接受的定义是:

“...普通课程,您专注于手头的业务问题,而不会出于与基础设施相关的原因添加内容...”

然而,我看到人们将 NHibernate 描述为一个允许忽略持久性的框架,但它是一个不能在任何标准 .NET 对象上工作的框架,只能在符合特定设计要求的标准 .NET 对象上工作,例如(来源):

  • 所有类都必须有一个默认构造函数
  • 除非类未密封并且所有成员都是虚拟的,否则某些功能将不起作用
  • 除非您滥用 Equals/GetHashCode,否则对象标识无法正常工作

(旁白:在任何人不高兴之前,我并不是要在这里选择 NHibernate,它只是一个经常被引用的框架示例,据称它允许持久性无知。我确信类似的论点可以应用于其他声称相同的 ORM .)

现在,尽管该类本身没有任何持久性框架特定的属性或基类等,但对我来说,它并不是真正的“不了解持久性”,因为它必须遵循一组设计准则以方便所选持久性框架的使用。您必须考虑到持久性框架的要求来设计和实现该类;如果您对此一无所知,则该课程可能无法使用。

我对“持久性无知”/“POCO”的定义有疑问的地方是,我不明白从概念上讲,这与添加属性(例如[Serializable]or [DataContract]or[XmlType]或任何其他持久性框架特定的注释)有什么不同这有助于使用该框架的实体的持久性和检索。

那么,究竟什么是“执着无知”呢?

显然,将其定义为能够持久化“普通类”是一个谬误,因为 NHibernate 仅在不引用特定于框架的类方面是普通的,而它们是非凡的,因为它们需要不寻常的设计选择,例如默认构造函数和所有- 可变类型的虚拟成员和 Equals/GetHashCode 实现。

因此,当对象有助于使用持久性框架(在设计和结构中或通过使用特定于框架的注释)但本身不执行任何持久性逻辑时,是否可以合理地说“持久性无知”是正确的?

4

8 回答 8

11

我会声称,像大多数事情一样,它是一个滑动比例。我们做的有些东西想要具有持久性。在规模的一端,这个东西具有所有的胆量、依赖关系和代码,这些都是定制的,可以以特定的方式持续存在这个东西。在规模的另一端是神奇地发生的事情,所有这些都不需要我们做更多的事情,而不仅仅是添加一个令牌或在某处设置一个属性,从而导致该事情“持续存在”。为了达到规模的神奇一面,有框架、设计指南、约定等来帮助神奇的发生。我认为您可能会争辩说,可以生产一种比 NHibernate 具有更少要求和限制但追求相同目标的工具;这个假设的工具将在我们的规模上更进一步。

我不知道我这么喜欢“坚持无知”这个词;它实际上是关于一个对象不知道实现,后备存储,缓存,诸如此类的事情 - 但是,一个对象通常知道它是否是持久的。但这只是语义。

于 2009-12-29T14:08:52.833 回答
7

我不相信您对“坚持不懈”的理解(或定义)是错误的。

真正的问题是抽象漏洞。很简单,现有技术很难实现真正的 PI。

于 2009-12-29T14:38:00.337 回答
4

持久无知类是不依赖于持久性框架的类。

也就是说,该类完全不知道存在持久性框架,它不从该框架定义的类继承,也不实现该持久性框架工作所需的接口。

于 2009-12-29T14:14:28.137 回答
4

我同意 Mikeb 的观点——“持久性无知”是一个滑动比例,而不是给定 ORM 的真/假属性。

我对真正 100% PI 的定义是,你可以坚持任何可能的 POCO 类,不管它与其他类有多么复杂和链接,而无需以任何方式改变类。

添加 ID 字段、用属性装饰、从 ORM 类继承、必须设计类以便它们很好地映射到 RDB 中的基础表——所有这些都将“PI 分数”降低到 100% 以下。

这就是说,我选择使用 Fluent NHibernate Automapping,因为它似乎在我看过的所有 ORM 选项中具有最高的 PI 分数。

于 2009-12-29T16:32:36.300 回答
1

我同意你的定义:

因此,当对象促进持久性框架的使用,但本身不执行任何持久性逻辑时,是否可以合理地说“持久性无知”是正确的?

类中的代码(相对于属性)没有持久性固有的特性。持久性可能需要默认构造函数,但没有实际执行持久性的代码。持久层可以进行相当大的更改,可以使用不同的数据库并且业务逻辑将保持不变。

于 2009-12-29T14:02:40.677 回答
0

尽管任何给定的持久性无知框架都可能存在某些较小的限制,但持久性无知仍然存在。

虽然你的领域模型中的一个类(通过 NHibernate 透明地持久化)必须有一个无参数的构造函数,以便它可以“动态地”构造它,但它不需要具有框架规定的某个基类,也不需要具有或覆盖某些框架指定的方法。

于 2009-12-29T14:08:18.153 回答
0

在我看来,“持久性无知”是您的模型(领域模型、业务模型或您可能称之为的任何东西)的属性。该模型不了解持久性,因为它通过抽象(有时称为存储库)检索它包含的实体的实例。这些抽象可以通过直接使用 ORM 来实现,但是正如您自己所说,这有时可能会增加对自然不属于您的模型的对象的要求。因此,我不会说遵循特定 ORM 某些要求的模型是 100% 不了解持久性的。

于 2009-12-29T14:17:00.113 回答
0

您可以使用域的类或应用程序和持久性中的 POCO 类来实现持久性无知,当您要将域对象映射到持久性类中并使用持久性对象与 nhibernate 或其他框架一起存储时

您的域类必须忽略信息是如何持久化的,因此您不能包含任何持久性框架的规则,例如(空构造函数、虚拟属性等)

这些持久性框架规则可以在你的持久性类中。

于 2018-07-04T18:52:26.907 回答