Java でのリポジトリパターンと DAO の違い
今日は、データアクセスオブジェクト(DAO)とリポジトリパターンについて学習します。この記事では、それらの違いについても説明します。
データアクセスオブジェクトパターン
このパターンはデータ永続性の抽象化であり、ほとんどがテーブル中心である基盤となるストレージに近いと見なされます。そのため、ほとんどの場合、データアクセスオブジェクト(DAO)はデータベーステーブルと一致し、醜いクエリを隠しながら、ストレージからデータを取得および送信する最も簡単な方法を可能にします。
リポジトリパターン
リポジトリパターンは、アプリケーションから保存されたデータを取得する手順であり、データストレージシステムのあらゆる側面を隠します。以下は、1つの user
をその username
で検索できるリポジトリインターフェイスです。
interface UserRepository {
User findUserByUsername(Username name);
}
これには、MySQL、Amazon DynamoDB、Web サービス、Oracle などのストレージテクノロジーに基づいた 1つまたは複数の実装を含めることができます。
リポジトリパターンは、データソースをアプリケーションの他の部分から分離するデザインパターンであるとも言えます。リポジトリは、データソース(Web サービスや永続モデルなど)とアプリケーションの残りの部分の間を仲介します。
以下は、リポジトリパターンの使用法をグラフで表したものです。
リポジトリはデータアクセスオブジェクト(DAO)に似ていますが、ビジネスロジックからデータを取得するために使用されているすべてのロジックを非表示にする抽象化であることを正しく理解しています。
モデルのラッパーのように動作し、永続ストアからのデータにアクセスします。リポジトリを使用する利点は、リポジトリを使用しているアプリケーションから、リポジトリの保存方法の正確な詳細を分離できることです。
常にユーザー
を返すがデータベースにはアクセスしないスタブコードを記述できるため、これはテストにとって非常に重要です。これにより、さまざまな問題から解放され、保存されたデータに依存しないアプリケーションコードの高速単体テストを作成できます。
Java のデータアクセスオブジェクト(DAO)とリポジトリパターンの違い
主な違いは、リポジトリは呼び出し元のレイヤーが理解できるオブジェクトのみを返すことです。ほとんどの場合、リポジトリはビジネスレイヤーによって使用されるため、ビジネスオブジェクトを出力します。
一方、データアクセスオブジェクトは、ビジネスオブジェクト全体ではない可能性のあるデータを返します。これは、データが有効なビジネスコンセプトではないことを意味します。
ビジネスオブジェクトがデータ構造のみである場合、モデリングの問題があることを示唆している可能性があります。これは悪い設計を意味しますが、リポジトリは少なくとも適切にカプセル化されたオブジェクトでより意味があります。
データ構造をロードまたは保存するだけの場合は、おそらくリポジトリは必要ありません。オブジェクトリレーショナルマッピング(ORM)で十分です。
リポジトリパターンは、他のさまざまなオブジェクト(集合体)で構成されるビジネスオブジェクトを処理する必要がある場合に最適なソリューションであり、この特定のオブジェクトでは、そのすべての部分が一貫している必要があります(集合体ルート)。
これは、完全な永続性情報を抽象化するためです。私たちのアプリケーションは製品
のみを要求し、リポジトリはそれを全体として返します。オブジェクトを復元するために必要なクエリ/テーブルの数は関係ありません。
ビジネスオブジェクトはオブジェクトリレーショナルマッピング(ORM)エンティティではないことに注意してください。技術的な観点からかもしれませんが、設計を考慮すると、1つはビジネスのものをモデル化し、もう 1つは永続性のものをモデル化します。
ほとんどの場合、直接の互換性はありません。
リポジトリパターンを使用することを好むいくつかの状況は次のとおりです。
- 大量のクエリが多いシステムで使用されます。
- 重複クエリを回避するためにリポジトリパターンを使用します。
- データストレージとドメイン(エンティティ)の間で使用されます。
- リポジトリが作成されたエンティティの仕様を使用して要素を検索および削除するためにも使用されます。
それでは、コードの実装によってこの違いを理解しましょう。
DAO とリポジトリパターンの実装の違い
データアクセスオブジェクトパターンの実装から始めましょう。
データアクセスオブジェクトパターンの実装
ここでは、以下にリストされている 3つのクラスが必要です。
- 基本的な
Employee
ドメインクラス Employee
ドメインに簡単な CRUD 操作を提供するEmployeeDAO
インターフェースEmployeeDAO
インターフェースを実装するEmployeeDAOImplementation
クラス
サンプルコード(従業員
クラス):
public class Employee {
private Long id;
private String employeeCode;
private String firstName;
private String email;
// write your getters/setters
}
サンプルコード(EmployeeDAO
インターフェイス):
public interface EmployeeDAO {
void create(Employee employee);
Employee read(Long id);
void update(Employee employee);
void delete(String employeeCode);
}
サンプルコード(EmployeeDAOImplementation
クラス):
public class EmployeeDAOImplementation implements EmployeeDAO {
private final EntityManager entityManager;
@Override
public void create(Employee employee) {
entityManager.persist(employee);
}
@Override
public Employee read(long id) {
return entityManager.find(Employee.class, id);
}
// ... continue with remaining code
}
JPA EntityManager Interfaceを使用して、基盤となるストレージと通信しています。また、Employee
ドメインのデータアクセスメカニズムを提供します。
リポジトリパターンの実装
このパターンは、オブジェクトのコレクションをシミュレートして、ストレージ、検索動作、および取得をカプセル化します。DAO と同様に、クエリを非表示にしてデータを処理しますが、アプリケーションのビジネスロジックに近いより高いレベルに位置します。
リポジトリは、DAO を使用してデータベースからデータをフェッチすることもできます。また、ドメインオブジェクトにデータを入力するか、ドメインからデータを準備して、永続化のために DAO を使用してストレージシステムに送信することもできます。
ここでは、次のクラスが必要です。
EmployeeRepository
インターフェースEmployeeRepositoryImplementation
クラス
サンプルコード(EmployeeRepository
インターフェイス):
public interface EmployeeRepository {
Employee get(Long id);
void add(Employee employee);
void update(Employee employee);
void remove(Employee employee);
}
サンプルコード(EmployeeRepositoryImplementation
クラス):
public class EmployeeRepositoryImplementation implements EmployeeRepository {
private EmployeeDAOImplementation employeeDAOImplementation;
@Override
public Employee get(Long id) {
Employee employee = employeeDAOImplementation.read(id);
return employee;
}
@Override
public void add(Employee employee) {
employeeDAOImplementation.create(employee);
}
// ... continue with remaining code
}
ここでは、EmployeeDAOImplementation
を使用してデータベースからデータを取得/送信します。したがって、リポジトリと DAO の実装は類似していると言えます。
これは、Employee
クラスが貧血のドメインであり、リポジトリがデータアクセス層(DAO)の上の別の層にすぎないためです。ただし、リポジトリはビジネスユースケースを実装するための最良の方法です。比較すると、データアクセスオブジェクトは、データにアクセスするための適切な候補に見えます。