【问题标题】:Designing DTO's and DO service layer设计 DTO 和 DO 服务层
【发布时间】:2012-12-20 10:54:55
【问题描述】:

我正在设计一个新的大型应用程序,它需要尽可能灵活。
我选择主要使用 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 中的某些内容?
谢谢,帕维尔。

【问题讨论】:

    标签: domain-driven-design dto service-layer


    【解决方案1】:

    此用例的通常工作流程是:按 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 映射器。

    【讨论】:

    • eulerfx,感谢您的回复!每次来自客户端的请求时访问数据库似乎还是有点奇怪。也许我应该创建一个像 UpdateCatName(id, name) 这样的方法?还是最好的做法是坚持使用 DTO?
    • 应用程序服务上的UpdateCatName(id, name) 之类的方法更好,因为它不需要新类。如果您的架构需要,DTO 可能仍然存在以支持传输。
    • @PavelTarno 我一直在做同样的事情。您是否考虑过域层的汇编器模式?如果您使用的是 DTO,您使用什么来发送消息?我认为它是 WCF 吗?至于汇编器模式,我在cs.sjsu.edu/~pearce/modules/patterns/enterprise/persistence/…(Java,但逻辑相同)和微软网站msdn.microsoft.com/en-us/library/ms978717.aspx找到了很棒的教程
    • Zack,我正在使用 WCF 进行消息传递。至于汇编程序,我之前使用 AutoMapper link 工作过,并且对结果非常满意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 2016-06-17
    • 2017-01-31
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多