Should services always return DTOs, or can they also return domain models? Ask Question

Should services always return DTOs, or can they also return domain models? Ask Question

I'm (re)designing large-scale application, we use multi-layer architecture based on DDD.

We have MVC with data layer (implementation of repositories), domain layer (definition of domain model and interfaces - repositories, services, unit of work), service layer (implementation of services). So far, we use domain models (mostly entities) across all layers, and we use DTOs only as view models (in controller, service returns domain model(s) and controller creates view model, which is passed to the view).

I'v read countless articles about using, not using, mapping and passing DTOs. I understand that there's no any definitive answer, but I'm not sure if it's ok or not returning domain models from services to controllers. If I return domain model, it's still never passed to the view, since controller always creates view-specific view model - in this case, it seem legit. On the other hand, it doesn't feel right when domain model leaves business layer (service layer). Sometimes service needs to return data object that wasn't defined in the domain and then we either have to add new object to the domain that isn't mapped, or create POCO object (this is ugly, since some services return domain models, some effectively return DTOs).

The question is - if we strictly use view models, is it ok to return domain models all the way to controllers, or should we always use DTOs for communication with service layer? If so, is it ok to adjust domain models based on what services need? (Frankly I don't think so, since services should consume what domain has.) If we should strictly stick to DTOs, should they be defined in service layer? (I think so.) Sometimes it's clear that we should use DTOs (e.g., when service performs lot of business logic and creates new objects), sometimes it's clear that we should use just domain models (e.g., when Membership service returns anemic User(s) - it seems it wouldn't make much sense to create DTO that is the same as domain model) - but I prefer consistency and good practices.

Article Domain vs DTO vs ViewModel - How and When to use them? (and also some other articles) is very similar to my problem, but it doesn't answer this question(s). Article Should I implement DTOs in repository pattern with EF? is also similar, but it doesn't deal with DDD.

Disclaimer: I don't intend to use any design pattern only because it exists and is fancy, on the other hand, I'd like to use good design patterns and practices also because it helps designing the application as a whole, helps with separation of concerns, even though using particular pattern isn't "necessary", at least at the moment.

ベストアンサー1

it doesn't feel right when domain model leaves business layer (service layer)

まるで内臓を抜き取っているような気分になりますよね? Martin Fowler によると、サービス レイヤーはアプリケーションの境界を定義し、ドメインをカプセル化します。つまり、ドメインを保護します。

時々、サービスはドメインで定義されていないデータオブジェクトを返す必要がある

このデータ オブジェクトの例を挙げていただけますか?

DTO に厳密に従う必要がある場合、それらはサービス層で定義される必要がありますか?

はい、応答はサービス レイヤーの一部であるためです。応答が「別の場所」で定義されている場合、サービス レイヤーはその「別の場所」を参照する必要があり、ラザニアに新しいレイヤーが追加されます。

ドメイン モデルをコントローラーまで返しても問題ありませんか、それともサービス層との通信には常に DTO を使用する必要がありますか?

DTO は応答/要求オブジェクトであり、通信に使用すると意味があります。プレゼンテーション層 (MVC コントローラー/ビュー、Web フォーム、ConsoleApp) でドメイン モデルを使用する場合、プレゼンテーション層はドメインに密接に結合されるため、ドメインに変更を加えるとコントローラーを変更する必要があります。

ドメインモデルと同じDTOを作成してもあまり意味がないようです)

これは、新しい視点から見ると、DTO の欠点の 1 つです。現時点では、コードの重複について考えていますが、プロジェクトが拡大するにつれて、特に異なるチームが異なるレイヤーに割り当てられているチーム環境では、それがはるかに理にかなっていることがわかります。WET 原則を参照してください。

DTO によりアプリケーションがさらに複雑になる可能性がありますが、レイヤーも同様に複雑になります。DTO はシステムの高価な機能であり、無料で提供されるものではありません。

DTOを使用する理由

この記事では、DTO を使用する利点と欠点の両方について説明します。http://guntherpopp.blogspot.com/2010/09/to-dto-or-not-to-dto.html

要約すると次のようになります。

使用する場合

  • 大規模プロジェクト向け。
  • プロジェクトの寿命は10年以上です。
  • 戦略的かつミッションクリティカルなアプリケーション。
  • 大規模チーム(5人以上)。
  • 開発者は地理的に分散しています。
  • ドメインとプレゼンテーションが異なります。
  • オーバーヘッドのデータ交換を削減します (DTO の本来の目的)。

使用してはいけない場合

  • 小規模から中規模のプロジェクト(最大 5 名)。
  • プロジェクトの存続期間は約2年です。
  • GUI、バックエンドなどに個別のチームはありません。

DTO に対する反論

DTO の引数

  • DTO がない場合、プレゼンテーションとドメインは密接に結合されます。(小規模なプロジェクトでは問題ありません。)
  • インターフェース/APIの安定性
  • 絶対に必要な属性のみを含むDTOを返すことで、プレゼンテーション層の最適化を実現できます。リンク投影エンティティ全体をプルする必要はありません。
  • 開発コストを削減するには、コード生成ツールを使用する

おすすめ記事