私は最近、データ転送オブジェクト(DTO)はアンチパターンであると言う人を耳にしました。
どうして?代替案は何ですか?
私は最近、データ転送オブジェクト(DTO)はアンチパターンであると言う人を耳にしました。
どうして?代替案は何ですか?
回答:
すべてのデータが2度あるプロジェクトもあります。1回はドメインオブジェクトとして、もう1回はデータ転送オブジェクトとして。
この複製には莫大なコストがかかるため、アーキテクチャはこの分離から大きな利益を得る必要があります。
DTOはアンチパターンではありません。ワイヤーを介して(たとえば、Ajax呼び出しのWebページに)データを送信する場合、宛先が使用するデータのみを送信することで帯域幅を節約する必要があります。また、多くの場合、プレゼンテーションレイヤーは、ネイティブビジネスオブジェクトとは少し異なる形式のデータを持っていると便利です。
これはJava指向の質問であることは知っていますが、.NET言語では匿名型、シリアル化、およびLINQにより、DTOをオンザフライで構築できるため、DTOを使用するためのセットアップとオーバーヘッドが削減されます。
EJB 3.0のAntiPatternのDTOは次のように述べています。
EJB 3.0より前のEJB仕様におけるエンティティBeanの重い性質により、データ転送オブジェクト(DTO)などの設計パターンが使用されていました。DTOは軽量のオブジェクトになり(そもそもエンティティBean自体である必要がありました)、層を越えてデータを送信するために使用されます...現在のEJB 3.0仕様では、エンティティBeanモデルがプレーンな古いJavaオブジェクト(POJO)と同じになっています。この新しいPOJOモデルを使用すると、エンティティごとまたはエンティティのセットごとにDTOを作成する必要がなくなります。層全体にEJB 3.0エンティティを送信する場合は、java.io.Serialiazableを実装するだけです。
DTO自体はアンチパターンではないと思いますが、DTOの使用に関連するアンチパターンがあります。ビル・ダドニーは、例としてDTO爆発に言及しています。
http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf
ここで言及されているDTOの乱用もいくつかあります。
http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/
これらは、階層間でデータを渡す手段として3層システム(通常はテクノロジーとしてEJBを使用)が原因で発生しました。Springなどのフレームワークに基づく最近のほとんどのJavaシステムは、POJOをドメインオブジェクト(JPAなどで注釈が付けられていることが多い)として単一層で使用する代替の簡略化されたビューを採用しています...ここでのDTOの使用は不要です。
オブジェクト指向の純粋主義者は、オブジェクトが実際のドメインオブジェクトではなくデータテーブル表現になるため、DTOはアンチパターンであると言います。
一部の人は、悪用の可能性があるため、DTOをアンチパターンと見なしています。彼らはしばしばそうするべきではない/する必要がないときに使用されます。
分散システムを構築している場合、DTOは反パターンではありません。誰もがそういう意味で開発するわけではありませんが、(たとえば)Open Socialアプリがあれば、すべてJavaScriptで実行されます。
APIに大量のデータを送信します。次に、これは何らかの形式のオブジェクト(通常はDTO / Requestオブジェクト)に逆シリアル化されます。これを検証して、入力したデータが正しいことを確認してから、モデルオブジェクトに変換できます。
私の意見では、誤用されているため、アンチパターンと見なされています。分散システムを構築していない場合は、それらを必要としない可能性があります。
意図データ転送オブジェクトは、異なるソースからのデータを格納し、データベース(またはにそれを転送することで、リモート・ファサード一度)。
ただし、DTOはデータを格納するだけでなく、データベース/ファサードとの間で転送するため、DTOパターンは単一責任の原則に違反しています。
データベースレイヤーを分離する必要があるため、データオブジェクトをビジネスオブジェクトから分離する必要はありません。とにかくん。
DTOの代わりに、オブジェクトのコレクション(Aggregate)とデータ転送(Repository)を分離するAggregate and Repository Patternsを使用する必要があります)。
オブジェクトのグループを転送するには、リポジトリのセットとトランザクションコンテキストを保持する作業単位パターンを使用できます。トランザクション内で集約内の各オブジェクトを個別に転送するため。
質問は「なぜ」ではなく、「いつ」である必要があります。
明らかに、それを使用した結果だけがより高いコストである場合、それはアンチパターンです(ランタイムまたはメンテナンス)。私は、データベースエンティティクラスと同一の何百ものDTOを持つプロジェクトに取り組みました。単一のフィールドを追加するたびに、DTOに、エンティティに、DTOからドメインクラスまたはエンティティへの変換、逆変換など、IDを4回追加します。いくつかの場所とデータを忘れました矛盾。
ドメインクラスの異なる表現が本当に必要な場合、それはアンチパターンではありません -よりフラットに、より豊かな、より狭いです、...
個人的には、ドメインクラスから始めて、適切な場所で適切にチェックして、それを渡します。「ヘルパー」クラスに注釈を付けたり追加したりして、マッピングを作成したり、データベースや、JSONやXMLなどのシリアル化形式に追加したりできます。必要に応じて、クラスを常に2つに分割できます。
それはあなたの視点についてです-私はドメインオブジェクトを、互いに作成された複数のオブジェクトではなく、さまざまな役割を果たす単一のオブジェクトとして見ることを好みます。オブジェクトの唯一の役割がデータの転送である場合、それはDTOです。