web-dev-qa-db-ja.com

プレーンオールドCLRオブジェクトとデータ転送オブジェクト

POCO = Plain Old CLR(またはそれ以上:Class)オブジェクト

DTO =データ転送オブジェクト

これで post 違いはありますが、率直に言って私が読んでいるブログのほとんどは、DTOが定義されている方法でPOCOについて説明しています。

POCOとDTOは同じものですか?

383
Patrick Peters

POCOはOOPの規則に従います。状態の振る舞いをするべきです(しかしそうである必要はありません)。 POCOはMartin Fowlerによって造られたPOJOから来ています[ ここでの逸話 ]。彼は、POJOという用語を、フレームワークを大量に使用するEJB実装を拒否することをよりセクシーにする方法として使用しました。 POCOは.Netでも同じ文脈で使われるべきです。フレームワークにオブジェクトのデザインを指示させないでください。

DTOの唯一の目的は状態を転送することであり、動作はしません。このパターンの使用例については、Martin Fowlerの DTOの説明 を参照してください。

違いは次のとおりです。POCOはプログラミングへのアプローチを説明します(古き良きオブジェクト指向プログラミング)、ここでDTOはオブジェクトを使用して「データを転送する」ために使用されるパターン

POCOはDTOのよ​​うに扱うことができますが、そうすると 貧血ドメインモデル を作成する危険があります。さらに、DTOはビジネスドメインの真の構造を表すのではなく、データを転送するように設計されるべきであるため、構造の不一致があります。この結果、DTOは実際のドメインよりもフラットになる傾向があります。

合理的に複雑な分野では、ほとんどの場合、別々のドメインPOCOを作成してそれらをDTOに変換することをお勧めします。 DDD(domain-driven design)は、 腐敗防止層 (別のリンク ここ を定義していますが、行うには 本を購入します )、分離を明確にするのに良い構造です。

553
Michael Meadows

私は自分のブログ記事で自分の立場をすでに述べたので貢献するのはおそらく冗長ですが、その記事の最後の段落では、次のようにまとめています。

つまり、POCOを愛することを学び、それがDTOと同じものであることについての誤った情報を広めないようにしてください。DTOは、アプリケーションのレイヤー間でデータを移動するために使用される単純なデータコンテナーです。 POCOは、永続性を無視すること(getメソッドやsaveメソッドは不要)という1つの要件を備えた、本格的なビジネスオブジェクトです。 C#で、それは素晴らしい読みです。

ところで、パトリック私はライフスタイルの記事としてPOCOを読み、私は完全に同意する、それは素晴らしい記事です。それは実際に私がお勧めするジミーニルソンの本からのセクションです。私はそれがオンラインで利用可能であることを知りませんでした。彼の本は、私がPOCO/DTO/Repository /そして他のDDD開発プラクティスで私が見つけた情報の最も良い情報源です。

49
Rudy

POCOは単に外部のフレームワークに依存しないオブジェクトです。それはPLAINです。

POCOに行動があるかどうかは重要ではありません。

DTOは、ドメインオブジェクトと同様にPOCOでも構いません(通常、動作は豊富です)。

通常、DTOはシステムの境界で終了するため、シリアル化の目的で外部フレームワーク(属性など)に依存する可能性が高くなります。

一般的なオニオンスタイルのアーキテクチャ(広くDDDのアプローチでよく使用される)では、ドメイン層は中央に配置されるので、この時点でそのオブジェクトはその層の外側に依存関係を持ってはいけません。

27
Neil

私はそのトピックについての記事を書きました: DTO対Value Object vs POCO

要するに:

  • DTO!=値オブジェクト
  • DTO⊂POCO
  • 値オブジェクト⊂POCO
14
Vladimir

DTOはPOCOになり得ると思います。 DTOはオブジェクトの使用法に関するものであり、POCOはオブジェクトのスタイルに関するものです(アーキテクチャーの概念から切り離されています)。

POCOがDTOとは異なる例として、ドメインモデル/ビジネスロジックモデル内のPOCOについて話しているときがあります。これは、問題のあるドメインのNice OO表現です。あなたはアプリケーション全体を通してPOCOを使うことができます、しかしこれは知識の漏洩のようないくつかの望ましくない副作用を持つかもしれません。 DTOは、例えばUIが通信するサービス層から使用され、DTOはデータのフラット表現であり、UIにデータを提供し、変更をサービス層に返送するためにのみ使用される。サービス層は、DTOの両方の方法をPOCOドメインオブジェクトにマッピングします。

更新Martin Fowler 言われた このアプローチは取るべき重い道であり、重大な不一致がある場合にのみ取るべきであることをドメイン層とユーザーインターフェイスの間。

6
Davy Landman

これが一般的なルールです:DTO ==悪と過剰設計されたソフトウェアの指標。 POCO ==いいね。 「エンタープライズ」パターンは、Java EEの世界の多くの人々の頭脳を破壊しました。 .NETで間違いを繰り返さないでください。

2
benmmurphy

DTOの主な使用例は、Webサービスからデータを返すことです。この場合、POCOとDTOは同等です。 POCOの動作はWebサービスから返されたときに削除されるため、動作があるかどうかは関係ありません。

1
John Saunders

TL; DR:

DTOは、状態転送のパターンを記述します。 POCOは何も記述しません。 OOPで「オブジェクト」と言う別の方法です。それは、POJO(Java)から来ています。これは、Martin Fowlerによって造られたものです。

DTOは、関心のあるレイヤー間で状態を転送するために使用されるオブジェクトパターンです。振る舞いによって状態が変化しない限り、振る舞いを持つことができます(つまり、技術的にはpocoになります)。たとえば、それ自体をシリアル化するメソッドがある場合があります。

POCOはプレーンなオブジェクトですが、「プレーン」とは、特別なものではないことを意味します。これは、暗黙のパターンを持たないCLRオブジェクトであることを意味します。一般的な用語。他のフレームワークで動作するように作られていません。たとえば、POCOのプロパティ全体に[JsonProperty]またはEFの装飾がある場合、POCOではないと主張します。

以下に、比較するさまざまな種類のオブジェクトパターンの例を示します。

  • View Model:ビューのデータをモデル化するために使用されます。通常、バインディングと検証を支援するデータ注釈があります。 MVVMでは、コントローラーとしても機能します。 DTO以上のものです
  • 値オブジェクト:値を表すために使用
  • Aggregate Root:状態と不変式の管理に使用
  • ハンドラー:イベント/メッセージへの応答に使用
  • 属性:横断的関心事に対処するための装飾として使用
  • サービス:複雑なタスクの実行に使用
  • Controller:要求と応答のフローを制御するために使用
  • Factory:コンストラクタが十分ではない場合に使用する複雑なオブジェクトを構成および/またはアセンブルするために使用されます。また、実行時に作成する必要があるオブジェクトを決定するためにも使用されます。
  • リポジトリ/ DAO:データへのアクセスに使用

これらはすべて単なるオブジェクトですが、それらのほとんどは一般にパターンに関連付けられていることに注意してください。したがって、それらを「オブジェクト」と呼ぶこともできますし、その意図をより具体的にして、それが何であるかによって呼び出すこともできます。これが、デザインパターンがある理由でもあります。いくつかの作品で複雑な概念を説明します。 DTOはパターンです。集約ルートはパターンであり、ビューモデルはパターンです(例:MVC&MVVM)。 POCOはパターンではありません。

POCOはパターンを記述しません。これは、OOPでクラス/オブジェクトを参照する異なる方法です。それを抽象的な概念と考えてください。彼らは何でも参照できます。 IMOには、一方向の関係がありますが、オブジェクトが1つの目的のみをきれいに処理できるようになると、POCOではなくなるためです。たとえば、あるフレームワークで動作するようにクラスを装飾でマークアップすると、POCOではなくなります。したがって:

  • DTOはPOCOです
  • POCOはDTOではありません
  • ビューモデルはPOCOです
  • POCOはビューモデルではありません

この2つを区別するポイントは、懸念を超えないようにし、密結合をもたらすために、パターンを明確かつ一貫したものにすることです。たとえば、状態を変更するメソッドを備えたビジネスオブジェクトがあり、APIエンドポイントを介して送り返すことができるように、SQL ServerおよびJsonPropertyに保存するためのEFデコレーションで地獄に装飾されている場合。そのオブジェクトは変更に耐えられず、プロパティのバリアント(たとえば、UserId、UserPk、UserKey、UserGuidなど)が散らばっている可能性があります。 APIエンドポイントでのJSON)。

ですから、もしあなたが何かがDTOであると私に言ったら、それはたぶん、それが状態を動かすこと以外に決して使われないことを確かめるでしょう。何かがビューモデルだと言ったら、おそらくデータベースに保存されていないことを確認するでしょう。何かがドメインモデルだと言ったら、おそらくドメイン外の何かに依存していないことを確認するでしょう。しかし、あなたが私に何かをPOCOだと言ったなら、あなたは本当に私にあまり多くを語っていないでしょう。

0
Sinaesthetic

DTOクラスは、さまざまなソースからのデータをシリアライズ/デシリアライズするために使用されます。あなたがソースからオブジェクトを逆シリアル化したいとき、それがどんな外部ソースであるかは問題ではありません:サービス、ファイル、データベースなどあなたはその一部だけを使いたいかもしれませんオブジェクトその後、そのデータを使用したいXModelにコピーします。シリアライザはDTOオブジェクトをロードするための美しいテクノロジです。どうして?オブジェクトをロード(逆シリアル化)するために必要な関数は1つだけです。

0