领域驱动设计中层之间的数据传输对象

Posted

技术标签:

【中文标题】领域驱动设计中层之间的数据传输对象【英文标题】:Data Trasfer Objects Between Layers in Domain Driven Design 【发布时间】:2013-11-13 19:53:55 【问题描述】:

域层通过数据传输对象 (DTO) 与其他层通信。我对 DTO 感到困惑。

DTO 1 位于域和表示层之间。

DTO 2 位于域和数据层之间。

我应该在层之间创建两个不同的 DTO 对象还是只创建一个 DTO。哪种方式更专业?

【问题讨论】:

如果是数据访问层,域层也应该对您的数据层一无所知。 【参考方案1】:

如果我们假设您使用两个单独的 DTO(DTO1 和 DTO2), 答案很简单: 在这种情况下,您必须创建两个单独的 DTO:DTO1 和 DTO2。 即使它们是相同的,它们也应该作为单独的类来实现。 这是因为 DTO1 是在域层中创建的,而 DTO2 是在数据层中创建的(根据您的图片)。

请注意,在某些解决方案中,不使用两个 DTO - 有时,只有一个 DTO。

【讨论】:

【参考方案2】:

让我们遍历所有层:

数据访问层 (DAL)。它用于从数据库(DB)中获取数据。

通常它知道Domain Entities 和域层。

DAL 可以返回Domain EntitiesDTOs (DB oriented data structures)。如果需要,可以使用这些 DTO 或域实体来构建表示层 (view models) 的 DTO。

域实体通常很重,需要data mappers 或任何ORM。我更喜欢使用Domain Entities,映射它们并避免使用其他 DTO。否则 DTO 也应该被映射。

域层(域模型)。它用于表示业务实体及其行为、业务规则、纯业务逻辑。

域层应该对实体存储在某处的方式一无所知(例如在数据库中)。它可以有自己的 DTO,可以是重构 Introduce Parameter Object 的结果。

表示层 (UI)。它用于向用户展示 UI。

它应该知道Data Access Layer 从数据库加载数据,知道Domain Layer 可以访问其业务逻辑。

它可以有自己的 DTO - 视图模型,它们是域实体的用户界面友好表示或 DB 友好 DTO。表示层有责任了解view models

如果您只打算有一个演示文稿,您的应用程序基础架构也可以作为演示层的一部分来实现,但通常它是一个单独的应用程序层。

【讨论】:

【参考方案3】:

您的图像显示了两个名为 DTO1 和 DTO2 的 DTO 对象。

DTO1 在表示层和域层之间共享数据。您可以将它们称为 ViewModel 类。

DTO2 在域和数据层之间共享数据。您可以将它们称为数据传输对象 (DTO)。

所以你可以使用两个不同的传输对象。

【讨论】:

【参考方案4】:

这真的取决于您的具体需求。

一般来说,您应该创建 2 组 DTO。这允许更好地解耦不同的层,并使您的系统架构更加灵活。需要的具体原因或情况例如:

可能无法共享 DTO,例如因为使用的技术存在差异,例如Web 服务和数据层用 C# 编写,表示层用 Java 编写。 DTO 不一定相同,即您用于与数据库层交互的 DTO 可以在数据库结构上建模,但您可以以不同方式将其暴露给表示层。

话虽如此,如果您可以忍受拥有一组 DTO 的限制,那么您可以共享它们(如果它适合您的需要),因为它产生的代码更少需要编写和维护。

【讨论】:

DTO2 类应该放在哪里?在域层或其他特定类库中 最好在单独的库中。它为您提供更好的分离性和灵活性。

以上是关于领域驱动设计中层之间的数据传输对象的主要内容,如果未能解决你的问题,请参考以下文章

领域驱动设计系列关键概念

面向对象领域驱动设计核心

大话领域驱动设计——应用层

DDD领域驱动设计-DDD概览

领域驱动设计架构风格

如何运用领域驱动设计 - 聚合