如何在DDD中实现持久性无知? [英] How to accomplish Persistance Ignorance in DDD?

查看:109
本文介绍了如何在DDD中实现持久性无知?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个涉及Workspace的项目的持久层上工作,每个持久化层可能包含零个,一个或多个Document. (我正在尝试遵循域驱动设计原则,但我的问题可能不是直接的与此相关.)

I am working on the persistence layer of a project that involves Workspace's, each of which may contain zero, one, or more Document's. (I am trying to follow Domain-Driven-Design principles but my questions may not be directly related to this.)

问题1:我应该分开持久性吗?也就是说,您是否以一种可以设计

Question 1: Should I separate out persistence? I.e., do you design you entity and value classes in such a way that you can

  • 在内存中创建实体和值,就像无需持久性(可能使用Factory方法Workspaces.newWorkspace(...))一样,并且
  • 调用单独的persist()方法(可能在存储库中)以保持持久性?
  • Create entities and values in memory, just as you would do without persistence (possibly using a Factory method Workspaces.newWorkspace(...)), and
  • Call a separate persist() method (possibly in a Repository) to take care of persistence?

还是我的工厂方法Workspaces.newWorkspace()创建一个 persisted 实体(一旦交易关闭,该实体就会保留)?

Or should my factory method Workspaces.newWorkspace() create a persisted entity (which will be persisted once the transaction closes)?

如果这个问题的答案是分离,伙计!" ,那么我想知道如何以一种优雅的方式来实现这一目标.我的第一种方法是(在 Scala 伪代码中):

If the answer to this question is "Separation, dude!" then I wonder how to accomplish this in an elegant way. My first approach was (in Scala pseudocode):

class Workspace(title: String, documents: List[Document], id: Option[Long]) {
  def add(d: Document) =  // ...
  def remove(d: Document) = // ...
}

但是,如果一个工作空间可以包含许多文档,那么这样做是不好的(受RAM限制).我的下一个方法,遵循如何不将服务注入实体" ,是这样的:

However, if a workspace can have many documents, this is not good (limited by RAM). My next approach, following "How not to inject services into entities", was this:

class Workspace(title: String, docSupplier: DocSupplier, id: Option[Long]) {
  def add(d: Document) = docSupplier.add(d)
  def remove(d: Document) = docSupplier.remove(d)
}

以此,工作空间工厂可以创建新工作空间,如下所示:

With this, the workspace factory can create new workspaces like this:

class Workspaces {
  def newWorkspace(title: String) = new Workspace(title,
    // A supplier that maintains a simple `List[Document]`
    new DocSupplier() {
      def add(d: Document) = list.add(d)
      def remove(d: Document) = list.remove(d)
    }, id)
}

此外,我的存储库可以重建工作空间,它是从数据库中获取的,如下所示:

Also, my repository can reconstruct workspaces it fetches from the database like this:

class WorkspaceRepository {
  def findById(id: Long) = // ... calls `createDoc()`

  def createDoc(...) = new Workspace(title,
    // A supplier that remembers changes so they can be persisted in `persist()`
    new DocSupplier() {
      def add(d: Document) = changes.rememberAdd(d)
      def remove(d: Document) = changes.rememberRemove(d)
    }, id)
}

问题2:这是这样做的方法吗? Puh,这是很多代码,并且有很多样板!

Question 2: Is this the way to do this?! Puh, it's a lot of code, with a lot of boilerplate!

推荐答案

我应该分离持久性吗?

Should I separate out persistence?

是的,只是您描述的方式.

Yes, just the way that you describe.

或者我的工厂方法Workspaces.newWorkspace()应该创建一个 持久实体(交易后将持久存在) 关闭)?

Or should my factory method Workspaces.newWorkspace() create a persisted entity (which will be persisted once the transaction closes)?

否,因为持久化瞬态实体应该是显式操作,例如添加新的Workspace时.工厂处理对象实例的创建,存储库处理持久性.如 pabrantes 所示,可以将工作单元模式与存储库结合使用.

No, because persisting a transient entity should be an explicit operation, such as when you add a new Workspace. The factory handles the creation of the object instance and the repository handles persistence. As indicated by pabrantes the Unit of Work pattern can be used in conjunction with repositories.

但是,如果一个工作区可以包含许多文档,那是不好的 (受RAM限制).

However, if a workspace can have many documents, this is not good (limited by RAM).

这是DDD中的常见情况-在达到持久性无知时,您必须考虑技术限制.首先要考虑的是Workspace实体是否完全需要引用Document实例的集合. Workspace是否需要强制执行不变式?有交易界限吗?对象引用仅

This is a common scenario in DDD - while reaching for persistence ignorance you have to consider technical constraints. The first thing to consider is whether the Workspace entity needs to reference the collection of Document instances at all. Are there invariants that Workspace needs to enforce? Are there transactional boundaries in place? Object references are only one of the ways of representing relationships. Another way is with a repository. So instead of having a Document collection on the Workspace class, you provide a repository method which allows retrieval of documents associated with a specific workspace. Given that the number of documents may be large, the repository can support paging and filtering as well.

也请参阅有效的总体设计,由沃恩·弗农(Vaughn Vernon)进行,以深入探讨这些问题.

Also take a look at Effective Aggregate Design by Vaughn Vernon for in depth treatment of these issues.

这篇关于如何在DDD中实现持久性无知?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆