在DDD中进行实体删除

red*_*edi 6 domain-driven-design ddd-repositories

我正在学习DDD,并有一个基本问题:

似乎在工厂,丰富的域模型,(CRUD的)Create,Read,Update存储库都已处理完了,但是删除又如何呢?在删除实体的地方可能存在一些业务逻辑?RepositoryImpl(属于基础结构)层不应该麻烦自己检查那些不变式,它的工作是从底层数据存储中删除给定的实体。这似乎与工厂的意图截然相反,但是DDD没有像“ kill”工厂那样的删除对象。

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

应该在哪里处理这种情况entity.delete()(有意义吗?)或在称为Delete的应用程序或域服务中处理这种情况。我担心的是,只要存储库接口具有称为delete的方法,任何客户端都可以绕过服务方法并直接调用回购方法。

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

Dmi*_*try 5

据我所知,对于DDD中的删除没有具体的指导原则(“删除”是一个非常通用且面向数据的术语)。它被称为“ 寿命终止 ”,是存储库的责任。在大多数情况下,生命周期的结束并不简单,并且与某些业务规则,状态更改等相关联。很多时候,域对象根本不会被删除,它们只是转换为“已存档”状态。我强烈建议阅读Udi Dahan 撰写的这篇文章

为了强制执行与对象寿命终止相关的不变量,您可以像下面这样构造代码:

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.");
    }
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

如果实现需要访问与Order关联的其他域对象,则方法'CanBeArchived'也可以是'OrderArchiver'接口的一部分。

  • 在该示例中,检测对象是否准备好进行归档的主要逻辑在域中(CanBeArchived方法)。基础结构层(存档器实现)只需调用此逻辑即可进行最终验证。基础结构层知道域对象,否则它将无法还原它们。 (2认同)