究竟什么是“持久性无知”?

时间:2009-12-29 13:50:51

标签: nhibernate orm poco data-access persistence-ignorance

持久性无知通常被定义为持续存在的能力。检索标准的.NET对象(如果你真的坚持给它们命名,那就是POCO)。而seemingly well accepted definition of a standard .NET object是:

  

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

但是,我看到人们将NHibernate描述为允许持久性无知的框架,但它是一个无法在任何标准.NET对象上工作的框架,只有标准.NET对象才能遵循特定的设计要求,例如(source):

  • 所有类必须具有默认构造函数
  • 除非打开类并且所有成员都是虚拟
  • ,否则某些功能不起作用
  • 除非您滥用Equals / GetHashCode
  • ,否则对象标识无法正常运行
  

(旁白:在任何人感到不安之前,我不打算在这里选择NHibernate,它只是一个经常被引用的框架示例,据说允许持久性无知。我敢肯定类似的论点可以应用于其他声称相同的ORM。)

现在虽然这个类本身没有任何持久性特定于框架的属性或基类等,但对我而言,它并不是“持久性无知”,因为它必须遵循一套设计指南来促进< / em>由所选的持久性框架使用。您必须考虑到持久性框架的要求来设计和实现该类;如果你不了解它,那么这个班可能无法使用它。

我在“持久性无知”/“POCO”的定义方面遇到问题,我在概念上看不出添加[Serializable]或{{等属性的方式有何不同1}}或[DataContract]或任何其他持久性框架特定的注释,促进使用该框架实体的持久性和检索。

那么,“持久性无知”到底是什么?

显然,将它定义为能够持久保存“普通类”是一种谬误,因为NHibernate只是在没有引用特定于框架的类的情况下是普通的,而它们非常特殊,因为它们需要不寻常的设计选择,例如默认构造函数和所有虚拟成员以及可变类型的Equals / GetHashCode实现。

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

8 个答案:

答案 0 :(得分:9)

我会声称,就像大多数事情一样,它的滑动比例。有些东西我们想要拥有持久性的属性。在规模的一端是这个东西具有所有的内容,依赖关系和自定义构建的代码,以便以特定的方式坚持这一件事。在规模的另一端是神奇地发生的事情,所有这些都没有我们做的更多,只是添加一个令牌或设置一个导致该东西“只是持久”的属性。为了达到规模的神奇面,有框架,设计指南,惯例等可以帮助实现魔法。我认为你可以争辩说,可以生产一种工具,它比NHibernate具有更少的要求和限制但追求相同的目标;这个假设工具将沿着我们的规模进一步发展。

我不知道我非常喜欢“坚持无知”这个词;它实际上是关于一个对象不知道实现,后备存储,缓存,那种东西 - 一个对象通常知道它是否是持久的。但那只是语义。

答案 1 :(得分:5)

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

真实问题是leaky abstractions的问题。很简单,现有技术使得非常难以实现真正的PI。

答案 2 :(得分:4)

我同意迈克 - “持久无知”是一个滑动尺度,而不是给定ORM的真/假属性。

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

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

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

答案 3 :(得分:1)

我同意你的定义:

  

这样说是否合理   “坚持无知”是真实的   对象便于使用   持久性框架,但不要   执行任何持久性逻辑   自己?

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

答案 4 :(得分:1)

一个持久的无知类,是一个与持久性框架无关的类。

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

答案 5 :(得分:0)

虽然任何给定的持久性 - 无知框架可能存在某些微小的限制,但仍然存在持久性 - 无知。

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

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

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

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