DDD - which layer DTO should be implemented

2020-05-21 09:02发布

问题:

I am learning about DDD so apologies if my question is naive. I think I need to use Local Data Transfer Object in order to display data to the users as a lot of properties are not part of any of Entity / Value Objects.

However, I am not sure where this DTO should be implemented - in a Domain Layer or in an Application Service Layer. The DTO implementation seems part of the Domain, but it means that when I create a collection of DTOs in the Service Layer and pass it to a Presentation Layer, I have to reference Domain Layer in Presentation Layer, which seems wrong.

What is the correct way to implement DTO using DDD principles?

回答1:

Place it in the Domain Service Layer. DTO is an output of that layer, it make sense if you define it there.

Don't put your DTO in the Domain Layer. The Domain Layer does not care about things outside of it's layer.

EDIT: The Domain Service layer is commonly known as the "Application Service Layer".



回答2:

Yorro is right about where to place DTO but I encourage you to avoid "DTO mindset". This way of thinking collides with DDD way of thinking.

Thinking about "I need a DTO here" is thinking about technical representation (as plalx says); it is a level of abstraction too low. Try a higer level of abtraction and think about your domain, user's tasks and your UI.

Do you need get view data to the user? Bring it to UI through a View Service that return a specific YourViewInfo class.

Do you need to send data to some Service to perform a task? Send it a specific TaskMessageInfo class or a specific Command class.

When you begin to modeling the internals of these classes is when you should start to thinking about its technical representation; then you could reach to the conclusion that could be, i.e., DTO classes for convenience.

Thinking this way helps you to model the system and doesn't trigger questions like

Where to put or belongs this thing?



回答3:

DTO and Domain are different layers.
So it requires mapping from one to another and usually it is done in what is called Application Services layer.
Take a look at the following articles to go deeper with DTO and layering:

  • Is Layering Worth the Mapping? by Mark Seemann
  • DTO vs Value Object vs POCO: definitions


回答4:

Such DTOs that are exposed to the outside world become part of a contract. Depending on their form, a good place for them is either the Application Layer or the Presentation Layer.

If the DTOs are only for presentation purposes, then the Presentation Layer is a good choice.

If they are part of an API, be it for input or output, that is an Application Layer concern. The Application Layer is what connects your domain model to the outside world.

As an interesting observation, it follows that the Presentation Layer should access the domain model only through the Application Layer. Otherwise, we lose our single point of access - we'd have multiple layers invoking the domain model. The Application Layer exposes all of our use cases. Whether they are invoked by a call from another service or by the Presentation Layer makes little difference.

Sources

The core of these concepts I learned from The Red Book by Vaughn Vernon. (I would quote from it, but I don't have it handy.) The chapters about the Application Layer and the Presentation Layer are relevant.

Primarily, my conclusions come from being strict with the concepts as presented by Eric Evans and Vaughn Vernon, and prioritizing freedom in the domain model, as this is Domain-Driven Design:

  • The domain model should be easy to change. That means not exposing domain objects externally, as having external dependants would make them hard to change (without breaking things).
  • The Application Layer is the external point of access. It is what defines the use cases on the domain model. That means not operating on the domain model from elsewhere. The Presentation Layer can only go through the Application Layer. Nobody likes having to deal with many different points of access!