1. 概要

このチュートリアルでは、データ転送オブジェクト(DTO)、値オブジェクト(VO)、プレーンオールドJavaオブジェクト(POJO)、およびJavaBeanとは何かを学習します。 それらの違いを見て、どのタイプをいつ使用するかを理解します。

2. プレーンオールドJavaオブジェクト

POJOは、Plain Old Java Objectとも呼ばれ、特定のフレームワークへの参照を持たない通常のJavaオブジェクトです。これは、単純で軽量なJavaオブジェクトを指すために使用される用語です。 。

POJOは、プロパティとメソッドに命名規則を使用しません。

3つのプロパティを持つ基本的なEmployeePOJOオブジェクトを定義しましょう。

public class EmployeePOJO {

    private String firstName;
    private String lastName;
    private LocalDate startDate;

    public EmployeePOJO(String firstName, String lastName, LocalDate startDate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.startDate = startDate;
    }

    public String name() {
        return this.firstName + " " + this.lastName;
    }

    public LocalDate getStart() {
        return this.startDate;
    }
}

ご覧のとおり、上記のJavaオブジェクトは、従業員を表す構造を定義しており、フレームワークに依存していません。

3. JavaBeans

3.1. JavaBeanとは何ですか?

JavaBean は、ほとんどがPOJOに似ていますが、実装方法に関する一連の厳密なルールがあります。 

ルールは、シリアライズ可能であり、コンストラクターがnullであり、 getX()および setX()の規則に従うメソッドを使用して変数にアクセスできるようにすることを指定しています。

3.2. JavaBeanとしてのPOJO

Java Beanは本質的にPOJOであるため、必要なbeanルールを実装して、EmployeePOJOをJavaBeanに変換しましょう。

public class EmployeeBean implements Serializable {

    private static final long serialVersionUID = -3760445487636086034L;
    private String firstName;
    private String lastName;
    private LocalDate startDate;

    public EmployeeBean() {
    }

    public EmployeeBean(String firstName, String lastName, LocalDate startDate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.startDate = startDate;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    // additional getters and setters
}

ここでは、POJOをJavaBeanに変換するために、 Serializable インターフェースを実装し、プロパティを private としてマークし、getter/setterメソッドを使用してプロパティにアクセスしました。

4. DTO

4.1. DTOパターン

データ転送オブジェクトとも呼ばれるDTOは、プロセス間またはネットワーク間でデータを伝送するために値をカプセル化します。

これは、呼び出されるメソッドの数を減らすのに役立ちます。 1回の呼び出しに複数のパラメーターまたは値を含めることで、リモート操作でのネットワークオーバーヘッドを削減します。

このパターンのもう1つの利点は、シリアル化のロジックをカプセル化することです。 これにより、プログラムは特定の形式でデータを保存および転送できます。

DTOには明示的な動作はありません。 基本的に、ドメインモデルをプレゼンテーション層から切り離すことにより、コードを緩く結合するのに役立ちます。

4.2. DTOの使用方法は?

DTOは、ビジネスロジックのないフラットな構造になっています。 これらは、POJOと同じ形式を使用します。 DTOには、シリアル化または解析に関連するストレージ、アクセサー、およびメソッドのみが含まれます。

DTOは基本的にドメインモデルにマッピングされるため、データをメソッドまたはサーバーに送信します。

従業員を作成するために必要なすべての詳細をグループ化するEmployeeDTOを作成しましょう。 APIとの相互作用を最適化する単一のリクエストで、このデータをサーバーに送信します。

public class EmployeeDTO {

    private String firstName;
    private String lastName;
    private LocalDate startDate;

    // standard getters and setters
}

上記のDTOはさまざまなサービスと相互作用し、データの流れを処理します。 このDTOパターンは、フレームワークの制限なしに任意のサービスで使用できます。

5. VO

VOは、Valueオブジェクトとも呼ばれ、java.lang.Integerjava.lang.Longなどの値を保持できる特殊なタイプのオブジェクトです。

VOは、常に equals()および hashCode()メソッドをオーバーライドする必要があります。 VOは通常、数字、日付、文字列などの小さなオブジェクトをカプセル化します。 それらは値のセマンティクスに従います。つまり、オブジェクトの値を直接変更し、参照の代わりにコピーを渡します。

値オブジェクトを不変にすることをお勧めします。 値の変更は、新しいオブジェクトを作成することによってのみ発生し、古いオブジェクト自体の値を更新することによっては発生しません。 これは、等しく作成された2つのValueオブジェクトが等しくなければならないという暗黙のコントラクトを理解するのに役立ちます。

EmployeeVO を定義し、 equals()メソッドと hashCode()メソッドをオーバーライドしてみましょう。

public class EmployeeVO {

    private String firstName;
    private String lastName;
    private LocalDate startDate;

    public EmployeeVO(String firstName, String lastName, LocalDate startDate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.startDate = startDate;
    }
    // Getters

    @Override
    public boolean equals(Object obj) {

        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;

        EmployeeVO emp = (EmployeeVO) obj;

        return Objects.equals(firstName, emp.firstName)
          && Objects.equals(lastName, emp.lastName)
          && Objects.equals(startDate, emp.startDate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(firstName, lastName, startDate);
    }
}

6. 結論

この記事では、POJO、JavaBeans、DTO、およびValueオブジェクトの定義について説明しました。 また、一部のフレームワークとライブラリがJavaBeanの命名規則を利用する方法と、POJOをJavaBeanに変換する方法についても説明しました。 また、DTOパターンと値オブジェクトをさまざまなシナリオでの使用法とともに確認しました。

いつものように、これらの例のコードはGitHubから入手できます。