domain-driven-design - 在 DDD 中删除实体

标签 domain-driven-design ddd-repositories

我正在学习 DDD 并且有这个基本问题:

似乎工厂、丰富的域模型、存储库(CRUD 的)创建、读取、更新都得到了处理,但是删除呢?删除实体可能有一些业务逻辑,您在哪里处理? RepositoryImpl(属于基础设施)层不应该检查那些不变量,它的工作是从底层数据存储中删除给定的实体。这似乎与工厂的意图截然相反,但 DDD 没有类似“杀死”工厂以进行删除的功能。

假设有一个用户可以删除的订单实体,但直到它处于“已完成”状态,所以客户端请求删除 repo.delete(ent)应该得到一个异常。同样,在某些情况下,当客户端请求删除时,它会导致更新(可能是状态更改或设置软删除标志)。

应该在哪里处理这种情况entity.delete() (这有意义吗?)或在称为删除的应用程序或域服务中。我担心的是只要Repository接口(interface)有那个叫做delete的方法,任何客户端都可以绕过服务方法直接调用repo方法。

只是为了添加一个上下文,我将如何构建我的层是通过 Java 包,并使用包可见性作为一种工具来禁止破坏层之间的交互。

最佳答案

据我所知,DDD 中的删除没有具体的指导方针(“删除”是一个非常通用且面向数据的术语)。它被称为“生命终结”,它是存储库的责任。大多数时候,生命的终结并不简单,并且与一些业务规则相关联,可能是状态更改等。很多时候域对象根本不会被删除,它们只是转换到“存档”状态。我强烈推荐阅读 this article乌迪·达汉。

为了强制执行与对象生命周期结束相关的不变量,您可以像这样构造代码:

class Order{
  ...
  bool CanBeArchived(){
    ...
  }
  ...
}

interface OrderArchiver {
  // throws InvalidOperationException if order can not be archived
  void Archive(Order order);
}

class NHibernateOrderArchiver implements OrderArchiver {      
  void Archive(Order order){
    if(!order.CanBeArchived()){
      throw new InvalidOperationException("Order can not be archived.");
    }
    ...
  }
}

如果实现需要访问与订单关联的其他域对象,方法“CanBeArchived”也可以是“OrderArchiver”接口(interface)的一部分。

关于domain-driven-design - 在 DDD 中删除实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11756146/

相关文章:

c# - 找不到 EntityBase 和 IAggregateRoot 引用?

c# - 存储库和使用原始 sql 查询?

design-patterns - 什么是聚合根?

java - 引用实体标识符的 DDD 值对象

domain-driven-design - DDD : Where to create entity objects?

python - 使用 DDD 和 Python 的大型服务器应用程序?

domain-driven-design - 处理贫血域模型的技术

domain-driven-design - 在域模型中的哪个位置最好保留对当前用户的引用?

c# - 跨聚合根搜索 child

language-agnostic - 其他存储库的 DDD 存储库感知