1

我正在设计一个需要尽可能灵活的新的大型应用程序。
我选择主要使用 DDD 进行设计。
我的问题是关于将 DTO 对象转移回我的服务层中的 DO 对象。

即:这是我映射到数据库的域对象(使用 ORM)

public class Cat  
{  
    int ID {get; set;}  
    string Name {get; set;}
    string BloodType {get; set;}
    string Color {get; set;}

    void Run(){...}
    void Purr() {...}
}

只有服务器操作需要方法和一些属性。
这就是我为这种猫类型设计另一个数据传输对象的原因:

public class CatDTO 
{  
    int ID {get; set;}  
    string Name {get; set;}
}

在中间,我将设置一个对象映射器来将我的 DO 转换为 DTO(反之亦然)。
当客户想要更新猫的名字时,他会调用这样的服务

public void UpdateCat(CatDTO cat)  
{
   // What will happen here?
   Cat serverCat = Mapper.GetCat(CatDTO);

   CatDao.SaveOrUpdate(serverCat);
}

当映射器将 DTO 对象转换回 DO 时,它必须命中 DB 以填充 Cat 对象的缺失属性(血型等)服务器端的其余部分无法使用 Cat 对象,因为它依赖于那些缺失的属性(即使我只是尝试更新数据库中的数据,我的 ORM 也会将血型字段更新为空字符串!)
我搜索了这个问题并且在网上找不到任何解释(或者至少有人像我一样被这个问题困扰)
我设计它的方式错误吗?也许我错过了我的 DDD 中的某些内容?
谢谢,帕维尔。

4

1 回答 1

4

此用例的通常工作流程是:按 ID 检索映射的域对象,应用 DTO 指定的更新,提交工作单元。您所说的 DAO 通常在 DDD 中称为存储库。代码应该更像:

public void UpdateCat(CatDTO catDto)  
{
   Cat cat = this.catRepository.Get(cat.ID);
   cat.Name = catDto.Name;
   this.catRepository.Commit();
}

Commit一步可以有多种方式。它可以是显式保存,也可以在UpdateCat方法之外提交工作单元。此工作流程也适用于所有相关场景。通常,域行为涉及检索适当的实体,在该实体上调用某些行为,然后将结果更改提交到数据库。

此外,DTO 不应直接映射回现有实体。相反,最好将它们视为表示要应用于现有实体的更改,并且代码应该反映这一点。这部分是因为现有实体由存储库“拥有”,并且存储库负责重构,而不是 DTO 映射器。

于 2013-01-06T20:42:17.563 回答