将 dto 包装在业务对象中 - 一个好主意吗?

Posted

技术标签:

【中文标题】将 dto 包装在业务对象中 - 一个好主意吗?【英文标题】:Wrapping dto inside a business object - a good idea? 【发布时间】:2015-03-11 05:05:08 【问题描述】:

我们正在启动一个新的多层架构。过去,我使用 AutoMapper 将数据传输对象映射到业务对象,反之亦然。一位同事建议,我们应该将 dto 包装在业务对象中,而不是映射。可能是通过在业务对象的构造函数中注入 dto。然后我们可以在没有映射的情况下即时访问 dto 的属性值。

问题:

是否推荐这种方法?

我知道,如果业务对象知道 dto,您就会引入紧密耦合。此外,通过在业务对象和 dto 之间创建 1:1 关系,您失去了一些灵活性,这通常 - 使用灵活的映射 - 将是 n:m 关系。

(见:Best Practices For Mapping DTO to Domain Object?)

这个缺点是似乎没有人使用包装方法的原因还是我错过了什么?

这是一个快速演示,我所说的“包装”是什么意思:

public class BusinessObject

    private Dto dto;

    public BusinessObject()
    
        this.dto = new Dto();
    

    public BusinessObject(Dto dto)
    
        this.dto = dto;
    


    public int Id
    
        get  return dto.Id; 
        set  dto.Id = value; 
    


public class Dto

    public int Id  get; set; 

感谢您的帮助!

托尔斯滕

【问题讨论】:

【参考方案1】:

这是一个有争议的问题。我第一次看到这种方法是在blog post。

好处很明显。它确实简化并简化了您的代码。现在,您的业务对象 (POCO) 不必重新创建 DTO 已经涵盖的大量访问器和修改器,而只需引用 DTO 的属性即可。创建业务对象也容易得多,因为您只需将 DTO 传递给业务对象构造函数,而持久化业务对象现在更容易,因为您只需要获取对象的 DTO 部分。

这种方法有一些缺点。正如您所指出的,您现在或多或少地被固定在 1-1 映射中。另一个缺点是您将失去业务对象可能对对象的某些属性强制执行的任何validation or business logic(因为 DTO 现在拥有它们)。

将 DTO 填充到业务对象 (POCO) 中的一个相当大的缺点是它可以留在代码中的那种行为,其中对象往往不再管理自己的状态。作为expressed here,这会使定位负责特定功能的代码变得相当困难。由于对象的状态是在外部设置的,因此这也使得使用这些类更加危险。

【讨论】:

嗨,德里克,感谢您的回答。我同意您的基本发现,即首先看包装方法似乎可以简化事情,但在以后的实施中,可能会出现问题。我倾向于将包装器方法用于大量显示的原始/不可编辑对象,其中验证和松散耦合不是问题。问候,托斯滕 托斯滕,我同意你对这个问题的看法。对于软件架构中的这个特定主题,没有一种万能的解决方案,并且对于某些不存在缺点的场景,它可以使用。

以上是关于将 dto 包装在业务对象中 - 一个好主意吗?的主要内容,如果未能解决你的问题,请参考以下文章

存储图形对象是个好主意吗?

QT:将我的域对象基于 QObject 是一个好主意吗?

具有业务对象、DTO 和实体/域对象的数据转换模式

typedef 指针是个好主意吗?

通过唯一的成员 ID 来识别对象是个好主意吗?

DTO DAO POCO BO