DTO、VO、POJO、JavaBeansの違いは?


584

同様の質問をいくつか見てきました。

また、それらが使用されているコンテキストを教えてください。またはそれらの目的?


1
POJOは、JavaBeansは制限が付属していても、上記の制限なしに付属している
exexzian

回答:


848

JavaBeans

JavaBeanは、Sunによって定義されたJavaBeansの規則に従うクラスです。ウィキペディアには、JavaBeansの概要がかなりわかります。

JavaBeansは、ビルダーツールで視覚的に操作できるJava用の再利用可能なソフトウェアコンポーネントです。実際には、特定の規則に準拠するJavaプログラミング言語で記述されたクラスです。これらは、多数のオブジェクトを単一のオブジェクト(Bean)にカプセル化するために使用されるため、複数の個別のオブジェクトとしてではなく、単一のBeanオブジェクトとして渡すことができます。JavaBeanは、シリアライズ可能なJavaオブジェクトであり、nullaryコンストラクターがあり、ゲッターメソッドとセッターメソッドを使用してプロパティにアクセスできます。

JavaBeanクラスとして機能するためには、オブジェクトクラスは、メソッドの命名、構成、および動作に関する特定の規則に従う必要があります。これらの規則により、JavaBeanを使用、再利用、置換、および接続できるツールを使用できるようになります。

必要な規則は次のとおりです。

  • クラスには、デフォルトのパブリックコンストラクターが必要です。これにより、編集およびアクティブ化フレームワーク内で簡単にインスタンス化できます。
  • クラスのプロパティは、標準の命名規則に従って、get、set、およびその他のメソッド(いわゆるアクセサーメソッドとミューテーターメソッド)を使用してアクセスできる必要があります。これにより、フレームワーク内でBeanの状態を簡単に自動検査および更新できます。その多くには、さまざまなタイプのプロパティ用のカスタムエディターが含まれています。
  • クラスはシリアライズ可能でなければなりません。これにより、アプリケーションとフレームワークは、VMとプラットフォームに依存しない方法でBeanの状態を確実に保存、保存、および復元できます。

これらの要件は、インターフェースの実装ではなく規則として主に表現されているため、一部の開発者は、JavaBeanを特定の命名規則に従うプレーンオールドJavaオブジェクトと見なしています。

POJO

プレーンオールドJavaオブジェクトまたはPOJOは、javax.ejbヘビーウェイトEJB 2.x(特にエンティティBean、ステートレスセッションBeanはそれほど悪いIMOではない)とは対照的に、インターフェースを実装しない単純な軽量Javaオブジェクトを表すために最初に導入された用語です。今日、この用語は、余分なものがない単純なオブジェクトに使用されます。繰り返しになりますが、ウィキペディアはPOJOの定義に優れています。

POJOは、Plain Old Java Objectの頭字語です。この名前は、問題のオブジェクトが通常のJavaオブジェクトであり、特別なオブジェクトではなく、特にEnterprise JavaBean(特にEJB 3より前)ではないことを強調するために使用されます。この用語は、2000年9月にマーティンファウラー、レベッカパーソンズ、ジョシュマッケンジーによって造られました。

「人々がなぜシステムで通常のオブジェクトを使用することに反対するのか疑問に思い、単純なオブジェクトには派手な名前が欠けていたためだと結論しました。そのため、それらに名前を付けたところ、非常にうまくキャッチされました。」

この用語は、テレフォニーでのPOTS(Plain Old Telephone Service)や、C ++で定義されているがC言語機能のみを使用するPODS(Plain Old Data Structures)など、派手な新機能を使用しないテクノロジの古い用語のパターンを引き継いでいます。およびPerlのPOD(Plain Old Documentation)。

この用語は、複雑なオブジェクトフレームワークと対照的な一般的で理解しやすい用語が必要なため、広く受け入れられている可能性が高いです。JavaBeanは、シリアライズ可能なPOJOであり、引数のないコンストラクターがあり、ゲッターメソッドとセッターメソッドを使用してプロパティにアクセスできます。エンタープライズJavaBeanは単一のクラスではなく、コンポーネントモデル全体です(ここでも、EJB 3はエンタープライズJavaBeanの複雑さを軽減します)。

POJOを使用する設計がより一般的になるにつれ、フレームワークで使用される機能の一部をPOJOに提供し、機能のどの領域が実際に必要かについてより多くの選択肢を提供するシステムが登場しました。HibernateとSpringがその例です。

値オブジェクト

値オブジェクトまたはVOは、java.lang.Integer値を保持するようなオブジェクトです(値オブジェクト)。より正式な定義については、よく値オブジェクトのマーティンファウラーの説明を参照します。

エンタープライズアプリケーションアーキテクチャのパターンでは、ValueオブジェクトをMoneyオブジェクトや日付範囲オブジェクトなどの小さなオブジェクトとして説明しました。それらの重要な特性は、参照セマンティクスではなく値セマンティクスに従うことです。

それらの等価性の概念はアイデンティティに基づいていないため、通常はそれらを区別できます。代わりに、すべてのフィールドが等しい場合、2つの値オブジェクトは等しくなります。すべてのフィールドは等しいですが、サブセットが一意である場合、すべてのフィールドを比較する必要はありません。たとえば、通貨オブジェクトの通貨コードは、等しいかどうかをテストするのに十分です。

一般的なヒューリスティックでは、値オブジェクトは完全に不変である必要があります。値オブジェクトを変更する場合は、オブジェクトを新しいオブジェクトに置き換え、値オブジェクト自体の値を更新できないようにする必要があります。更新可能な値オブジェクトはエイリアスの問題を引き起こします。

初期のJ2EE文献では、値オブジェクトという用語を、私がデータ転送オブジェクトと呼んでいる別の概念を説明するために使用していました。その後、使用方法を変更し、代わりにオブジェクト転送という用語を使用しています。

ウィキDirk Riehleで、価値のあるオブジェクトに関するより良い資料を見つけることができます。

データ転送オブジェクト

データ転送オブジェクトまたはDTOは、EJBで導入された(アンチ)パターンです。EJBで多くのリモート呼び出しを実行する代わりに、ネットワーク経由で転送できる値オブジェクトであるデータ転送オブジェクトにデータをカプセル化するという考えがありました。ウィキペディアには、データ転送オブジェクトの適切な定義があります

以前は値オブジェクトまたはVOと呼ばれていたデータ転送オブジェクト(DTO)は、ソフトウェアアプリケーションサブシステム間でデータを転送するために使用される設計パターンです。DTOは多くの場合、データベースからデータを取得するためにデータアクセスオブジェクトと組み合わせて使用​​されます。

データ転送オブジェクトとビジネスオブジェクトまたはデータアクセスオブジェクトの違いは、DTOはそれ自体のデータ(アクセサとミューテータ)の格納と取得を除いて、動作がないことです。

従来のEJBアーキテクチャでは、DTOは2つの目的を果たします。まず、エンティティBeanがシリアル化できないという問題を回避します。次に、ビューで使用されるすべてのデータがフェッチされ、DTOにマーシャリングされてからプレゼンテーション層に制御が戻るアセンブリフェーズが暗黙的に定義されます。


したがって、多くの人にとって、DTOとVOは同じものです(ただし、FowlerはVOを使用して、私たちが見た別の何かを意味します)。ほとんどの場合、これらはJavaBeansの規則に従っているため、JavaBeansでもあります。そして、すべてPOJOです。


1
したがってclass SomeClass { public String foo;public String bar; }、複雑なロジックがたくさんあるクラス内で、このような無関係なデータを転送するためだけに作成された便利なクラスがある場合、JavaBeanではないことを確認してください。変更可能であるため、VOにすることはできません。 DTO?それは、いかなる種類のリモート呼び出しも対象としていません。POJOと見なされますか?
ハイメHablutzel 2014年

3
@ user2601512:まだBeanです。:P Beanに動作があることには何の問題もありません。実際、それはかなり期待されています。他に何もしない場合は、基本的にDTOです。
cHao

7
@xSNRG:他のコードが作用するデータにオブジェクトを降格させるためです。これは、オブジェクトが動作し、オブジェクト自身の状態に責任を持つ必要があるOOの観点から後退したステップです。実際にデータを転送しているだけなら、DTOはまともな解決策になる場合があります。つまり、名前ですが、カプセル化は基本的に対象外となり、通常、実際のオブジェクトが提供できる有効性/一貫性の保証が失われます。
cHao 2017年

1
@KumaresanPerumal:できれば、できます。ただし、モデルはデータレイヤーとは異なり、目的やルールが異なります。データレイヤーは通常、すべてのレイアウトと任意に設定可能なものを必要とし、モデルは理想的にはデータを非表示にして不変条件を適用することを望んでいます。ストレージにモデルオブジェクトを使用したい場合は、どちらかで妥協する必要があります。
cHao 2017

1
@KumaresanPerumal:データを格納および取得するためのデータレイヤーがあります。これを行うには、データを保持しているオブジェクトへの完全なアクセスが必要ですが、検索とは、オブジェクトのどこかに値を設定することを意味するためです。しかし、モデルはシステム内のデータを管理し、カプセル化のようなOOの原則に拘束されます。オブジェクトは内部状態の制御を維持し、他のコードが内部をいじり回してはならないという考えです。DTOはそのギャップを埋めることができます。データ層はそれらに自由にアクセスでき、モデルは制御を放棄する必要はありません。
cHao

66

DTO対VO

DTO-データ転送オブジェクトは、レイヤーと層の間でデータを転送するために使用される単なるデータコンテナーです。

  • 主に属性が含まれています。ゲッターとセッターなしでパブリック属性を使用することもできます。
  • データ転送オブジェクトには、ビジネスロジックは含まれていません。

類推:
属性のユーザー名、パスワード、および電子メールIDを持つ単純な登録フォーム。

  • このフォームがRegistrationServletファイルで送信されると、ビューレイヤーからビジネスレイヤーにすべての属性が取得され、そこでJava Beanに属性が渡され、次にDAOまたは永続性レイヤーに属性が渡されます。
  • DTOは、ビューレイヤーからビジネスレイヤーに、そして最後に永続レイヤーに属性を転送するのに役立ちます。

DTOは主に、ネットワークを介して効率的にデータを転送するために使用されました。JVMから別のJVMに送信される場合もあります。

多くの場合java.io.Serializable、DTOは-JVM 間でデータを転送するためです。

VO-値オブジェクト[1] [2]は、それ自体がデータの固定セットを表し、Java列挙型に似ています。値オブジェクトのIDは、オブジェクトIDではなく状態に基づいており、不変です。実際の例としては、Color.RED、Color.BLUE、SEX.FEMALEなどがあります。

POJOとJavaBeans

[1] POJOのJava-Beannessは、そのプライベート属性がすべてJavaBeans規約に準拠するパブリックゲッターとセッターを介してアクセスされることです。例えば

    private String foo;
    public String getFoo(){...}
    public void setFoo(String foo){...}; 

[2] JavaBeansはSerializableを実装し、引数のないコンストラクターを持つ必要がありますが、POJOではこれらの制限はありません。


コメントすみません、遅くなりましたが、それらの違いについて学び、質問があります。Java Beanクラスがあるが、doSomething()などの別のメソッドがある場合はどうなりますか?どんなクラスですか?よろしくお願いします
jscherman 2014年

@srinivas DOMAINまたはMODEL javaオブジェクトでデータを渡せないのはなぜですか?しかし、私はDTOなしのモデルを使用しています。簡単に説明してください。ありがとう
Kumaresan Perumal 2017

46

基本的に、

DTO:「データ転送オブジェクト」は、ソフトウェアアーキテクチャの別のレイヤー間を移動できます。

VO:「値オブジェクト」は、Integer、Moneyなどのオブジェクトを保持します。

POJO:特別なオブジェクトではないプレーンな古いJavaオブジェクト。

Java Beans:Java Classがシリアライズ可能で、no-arg各フィールドにコンストラクターとゲッターとセッターが必要です


これらの説明はほとんど間違っている/不完全です。
cellepo

24

Java BeanはEJBと同じものではありません。

Java 1.0 のJavaBeans仕様は、VBのように見えるIDEでJavaオブジェクトを操作できるようにするSunの試みです。「Java Beans」として認定されたオブジェクトに対して定められたルールがありました。

  1. デフォルトのコンストラクタ
  2. 適切な命名規則に従ったプライベートデータメンバーのゲッターとセッター
  3. シリアライズ可能
  4. 多分私が忘れている他のもの。

EJBは後で登場しました。分散コンポーネントとトランザクションモデルを組み合わせ、スレッド、プーリング、ライフサイクルを管理し、サービスを提供するコンテナーで実行します。Java Beansとはかけ離れています。

DTOは、Javaのコンテキストで生まれました。なぜなら、EJB 1.0仕様はデータベースに対して「おしゃべり」であることが知られているからです。すべてのデータ要素を往復するのではなく、人々はそれらをまとめてJava Beansにパッケージ化して出荷します。

POJOはEJBに対する反応でした。


1
私は間違っていたので、メッセージを削除したいと思いました。訂正ありがとうございます。POJOの意味が少し前に変わったことに注意したい。まず、それらはプライベートプロパティとそのアクセサーのみで構成されています。ここで、POJOを注釈付きのクラス、他のクラスの実装および拡張などと
見なします

質問が尋ねたように、VOはどうですか?完全な質問に答えるまで、これは答えではありません
cellepo

4

POJO:他のJavaファイル(クラス)を拡張または実装しないJavaファイル(クラス)です。

Bean:これは、すべての変数がプライベートで、メソッドがパブリックであり、適切なゲッターとセッターが変数へのアクセスに使用されるjavaファイル(クラス)です。

通常のクラス:これは、public / private / default / protected変数で構成されるJavaファイル(クラス)であり、別のJavaファイル(クラス)を拡張または実装する場合としない場合があります。


質問が尋ねたように、VOはどうですか?完全な質問に答えるまで、これは答えではありません
cellepo

1

最初の話

通常のクラス -つまり、Javaでは通常のクラス定義です。つまり、さまざまなタイプのメソッドプロパティなどを作成します
。Bean- Beanは、このBeanを使用する特定のクラスのオブジェクトだけではなく、オブジェクトと同じようにJavaクラスにアクセスできます。

その後、最後の1つのPOJOについて話します

POJO - POJOは、サービスを持たないクラスであり、デフォルトのコンストラクターとプライベートプロパティ、および対応するsetterメソッドとgetterメソッドに値を設定するためのプロパティしかありません。これは、Plain Java Objectの短縮形です。


質問が尋ねたように、VOはどうですか?完全な質問に答えるまで、これは答えではありません
cellepo

1
  • 値オブジェクト:オブジェクトの値に基づいてオブジェクトの同等性を測定する必要がある場合に使用します。
  • データ転送オブジェクト:複数の属性を持つデータを、リモートサーバーへの複数の呼び出しを回避するために、レイヤー全体でクライアントからサーバーに一度に渡します。
  • プレーン・オールドJavaオブジェクト:単純なクラスのプロパティであり、引数のないパブリック・コンストラクターです。JPAエンティティーについて宣言したとおり。

値オブジェクトオブジェクトパターンとデータ転送パターンの違い

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.