1. ホーム
  2. asp.net-mvc

[解決済み】サービスは常にDTOを返すべきですか、それともドメインモデルも返すことができますか?

2022-04-02 03:34:49

質問

大規模なアプリケーションを設計しているのですが、DDDに基づく多層アーキテクチャを使用しています。

私たちは、データ層(リポジトリの実装)、ドメイン層(ドメインモデルとインターフェイスの定義 - リポジトリ、サービス、作業単位)、サービス層(サービスの実装)でMVCを構成しています。これまでのところ、すべての層でドメインモデル(主にエンティティ)を使用し、DTOはビューモデルとしてのみ使用しています(コントローラで、サービスがドメインモデルを返し、コントローラがビューモデルを作成し、ビューに渡されます)。

DTOの使用、不使用、マッピング、パスについて数え切れないほどの記事を読みました。明確な答えがないことは理解していますが、サービスからコントローラーにドメインモデルを返してもいいのか悪いのかよくわかりません。もしドメインモデルを返したとしても、コントローラは常にビュー専用のビューモデルを作成するため、ビューに渡されることはありません - この場合、合法的に見えます。一方、ドメインモデルがビジネスレイヤー(サービスレイヤー)から離れると、違和感があります。サービスによっては、ドメインで定義されていないデータオブジェクトを返す必要があり、その場合、マッピングされていない新しいオブジェクトをドメインに追加するか、POCOオブジェクトを作成しなければなりません(あるサービスはドメインモデルを返し、あるサービスは事実上DTOを返すので、これは醜いことです)。

ビューモデルを厳密に使用する場合、コントローラまでドメインモデルを返しても良いのか、それともサービス層との通信には常にDTOを使用すべきなのか、ということです。もしそうなら、サービスが必要とするものに基づいてドメインモデルを調整してもいいのでしょうか?(DTOにこだわるのであれば、サービス層で定義すべきなのでしょうか?(DTOを使うべきことが明らかな場合(例:サービスが多くのビジネスロジックを実行し、新しいオブジェクトを作成する場合)と、ドメインモデルだけを使うべきことが明らかな場合(例:メンバーシップサービスが貧弱なユーザーを返す場合、ドメインモデルと同じDTOを作成してもあまり意味がないようです)があります - 私は一貫性と優れた実践を好みます。

記事 ドメイン vs DTO vs ViewModel - どのように、いつ使うのか? (そして他の記事も)私の問題と非常によく似ていますが、この質問(複数可)には答えていません。記事 EFでリポジトリパターンのDTOを実装すべき? も似たようなものですが、DDDは扱ってないです。

一方、良いデザインパターンとプラクティスは、アプリケーション全体の設計に役立ち、関心事の分離に役立つので、特定のパターンを使うことは、少なくとも現時点では必要ではありませんが、使いたいと思っています。

どのように解決するの?

<ブロッククオート

ドメインモデルがビジネス層(サービス層)から離れると違和感がある

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

<ブロッククオート

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

このデータオブジェクトの例を教えてください。

DTOに厳密にこだわるのであれば、サービス層で定義すべきでしょうか?

はい、レスポンスはサービスレイヤーの一部だからです。もしそれが他のどこかで定義されているなら、サービス層はその他のどこかを参照する必要があり、ラザニアに新しい層が追加されることになります。

<ブロッククオート

それとも、サービス層との通信には常にDTOを使用すべきでしょうか?

DTOはレスポンス/リクエストオブジェクトなので、通信に使うなら理にかなっています。もし、プレゼンテーション層(MVC-Controllers/View, WebForms, ConsoleApp)でドメインモデルを使用している場合、プレゼンテーション層はドメインと密接に結合しており、ドメインを変更するとコントローラを変更する必要があります。

<ブロッククオート

ドメインモデルと同じDTOを作ってもあまり意味がないような気がするのですが......。)

これは、新しい目から見たDTOのデメリットの一つです。今、あなたはこう思っています。 コードの重複 しかし、プロジェクトが拡大するにつれ、特に異なるチームが異なるレイヤーに割り当てられるチーム環境では、より理にかなったものになるでしょう。

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がない場合、プレゼンテーションとドメインは緊密に結合されています。(小規模なプロジェクトではこれでOK)
  • インターフェース/APIの安定性
  • 絶対に必要な属性のみを含むDTOを返すことにより、プレゼンテーション層の最適化を提供することができる。使用方法 linq-projection を使えば、エンティティを丸ごと引っ張る必要はない。
  • 開発コストを削減するために、コード生成ツールを利用する