持久性无关对象能够实现延迟加载吗?


12

持久性无知是单责任原则的应用,这实际上意味着域对象(DO)不应该包含与持久性相关的代码,而应该只包含域逻辑。

a)我认为这意味着联系较低层(即持久层)的代码位于业务逻辑层的其他类(OC)中的域模型之外?

B)如果我的假设下一个)是正确的,那么DO,说Customer,从来没有包含的方法如GetCustomersGetCustomerByID

c)如果我在a)b)假设是正确的,并且假设Customer域对象对其属性的某些属性使用了延迟加载,则在某个时候Customer,内部逻辑必须联系OC,而OC则会检索延迟的数据。但是,如果Customer需要联系OC来接收延迟的数据,那么我们真的不能说域对象不包含与持久性相关的逻辑吗?

谢谢

回复jkohlhepp

1)我假设OrderProvider并且CustomerProvider类包含在业务逻辑层中?

2)我从您的答复中得知,b)下的假设是正确的?

3)

...我将检查是否填充了一些私人订单字段或该字段是否为空。如果为空...

但是据我所知,只要域代码需要检查是否order填充了私有字段,如果没有,请联系OrderProvider,我们已经违反了PI原则?

Answers:


4

我相信您关于持久性无知的假设A和B是正确的。

如何最好地完成数据库对象的延迟加载在很大程度上取决于您的特定问题和实现。但是,我将尝试对如何进行延迟加载同时保持持久性和域逻辑类之间的关注点分离进行一般性回答。

我倾向于使用以下类来实现持久性无知:

  • 领域类别-例如客户
  • 提供程序/存储库类-例如CustomerProvider
  • 通用数据库查询类-例如DatabaseQuery

DatabaseQuery类将负责使用数据库驱动程序来查询数据库并将结果数据组装到通用结果集中,例如DataTable。CustomerProvider将负责使用DatabaseQuery类对数据库执行SQL,并使用该SQL的结果来组装Customer实例。客户将是“纯”域对象,其中包含与客户相关的数据和逻辑。

至于提供程序类应该在业务层还是在数据层,我没有很强的意见。我可以看到两种情况。重要的部分是您将各个类的职责分开。

现在让我们讨论延迟加载。假设我希望客户拥有一组订单,但是除非消费者尝试访问这些订单,否则我不希望将订单从数据库中拉出。我将在“客户”上创建一个名为“订单”的属性。在该属性的getter中,我将检查是否填充了一些私人订单字段或该字段是否为null。如果为null,请使用OrderProvider从数据库加载订单。否则,仅返回已经加载的集合。

在我看来,要接触OrderProvider需要客户并没有违反PI。客户仍然不知道如何获得订单。它只是知道它是从OrderProvider获取它们的。可能还有其他原因使Customer与OrderProvider脱钩,但我认为PI在这里不是问题。

假设您正在手动执行持久性无知。如果使用的是ORM框架(例如Entity Framework或Hibernate),则这些框架通常具有自动支持延迟加载的功能。


嗨,如果您有时间-我已编辑我的帖子以回复您的答案
user1483278 2012年

1
@ user1483278我编辑了答案,希望能解决这些问题。
RationalGeek

PI代表什么?
Kugel

持久性无知
RationalGeek

2

您只有一些可填充域对象的关联类(例如,称为“存储库”的类)。您可以实施延迟加载或所需的任何类型的缓存一致性方案,而域对象则不明智。您正在将填充域对象的职责与成为域对象的职责分开。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.