DAOとリポジトリのパターンの違いは何ですか?


423

データアクセスオブジェクト(DAO)とリポジトリパターンの違いは何ですか?Enterprise Java Beans(EJB3)、インフラストラクチャーとしてHibernate ORM、設計手法としてドメイン駆動設計(DDD)とテスト駆動開発(TDD)を使用してアプリケーションを開発しています。

回答:


472

DAOデータの永続性を抽象化したものです。オブジェクトのコレクションの
Repository抽象化です

DAO多くの場合、テーブル中心のデータベースに近いと見なされます。
Repositoryドメインに近いと見なされ、集合ルートでのみ処理されます。

Repositoryを使用して実装できますDAOが、反対のことはできません。

また、a Repositoryは一般に狭いインターフェースです。これは、と、単にオブジェクトのコレクションである必要がありGet(id)Find(ISpecification)Add(Entity)

のようなメソッドUpdateはで適切ですが、DAOではありませんRepository-を使用するRepository場合、エンティティへの変更は通常、個別のUnitOfWorkによって追跡されます。

と呼ばれる実装Repositoryが本当にのより多く見られることは一般的であるように思われるDAOため、それらの違いについてはいくつかの混乱があると思います。


27
まあ、DAOクラスに文字通りIRepositoryインターフェイスを実装させたくないでしょう。リポジトリで実装にDAOを使用する必要があります。DAOはテーブルごとのオブジェクトになりますが、リポジトリはほとんどの場合、単一のエンティティを構築するために複数のDAOを使用する必要があります。そうでない場合、リポジトリとエンティティが単一のテーブルにアクセスするだけでよい場合は、貧血ドメインを構築している可能性があります。
クエンティン・スターリン

29
.NETの世界では、特に「リポジトリ」という用語は、基本的にDAOを指すのに使用されていることに気付きました。"DAO"は、Java用語です。
ウェインモリーナ

14
@Thurein DAO-sはテーブルごとではなく、パターンはデータへのアクセスを抽象化するだけです-好きなように実装できます(テーブルごと、またはグループまたはモデルごと)。推奨される方法は、基礎となる永続性を考慮に入れるのではなく、常にドメインモデルに基づいてDAOを形成することです。これにより、使いやすく/明確になり、永続化の方法が少し柔軟になります(たとえば、必要になると想像してください)。データをXMLファイルに格納するか、データベースではなくメッセージキューから取得するDAO ...)。
Stef

21
@Stef同意しない。DAOは、その定義(データアクセスオブジェクト)によってデータを返します。リポジトリは、その定義により、ドメインオブジェクトを返します。OOPでは1つ以上のデータオブジェクトからドメインオブジェクトを作成し、その逆ではないため、リポジトリがDAOを使用し、その逆は使用しないことは当然のことです。
ミハイダニーラ2013

6
DAOが「読み取りと書き込み」であるのに、なぜリポジトリは「読み取り専用」の概念なのですか?
Dennis

121

わかりました、私がコメントに入れたものをよりよく説明できると思います:) つまり、DAOはリポジトリよりも柔軟なパターンですが、基本的には両方を同じように見ることができます。両方を使用したい場合は、DAOでリポジトリを使用します。以下でそれぞれについて説明します。

リポジトリ:

これは、特定のタイプのオブジェクトのリポジトリです。特定のタイプのオブジェクトを検索したり、保存したりできます。通常は、1つのタイプのオブジェクトのみを処理します。たとえばAppleRepository、あなたがすることができますAppleRepository.findAll(criteria)またはAppleRepository.save(juicyApple)。リポジトリはドメインモデルの用語を使用していることに注意してください(DBの用語ではなく、データがどこに永続化されるかとは関係ありません)。

リポジトリはほとんどの場合、同じテーブルにすべてのデータを格納しますが、パターンはそれを必要としません。ただし、1種類のデータしか処理しないため、1つのメインテーブルに論理的に接続されます(DB永続化に使用する場合)。

DAO-データアクセスオブジェクト(つまり、データへのアクセスに使用されるオブジェクト)

DAOは、データを検索するクラスです(ほとんどの場合はファインダーですが、一般的にはデータの格納にも使用されます)。パターンは同じタイプのデータを格納することを制限しないため、関連オブジェクトを検索/格納するDAOを簡単に作成できます。

たとえば、次のようなメソッドを公開するUserDaoを簡単に作成できます。

Collection<Permission> findPermissionsForUser(String userId)
User findUser(String userId)
Collection<User> findUsersForPermission(Permission permission)

これらはすべてユーザー(およびセキュリティ)に関連しており、同じDAOで指定できます。これは、リポジトリには当てはまりません。

最終的に

両方のパターンは実際には同じことを意味します(データを格納し、データへのアクセスを抽象化し、両方ともドメインモデルに近く表現され、DB参照をほとんど含みません)。ただし、DAOの使用方法は少し異なる場合があります。もう少し柔軟で汎用的ですが、リポジトリはもう少し具体的でタイプのみに制限されます。


これを正しく取得する場合、CarDescriptionたとえばlanguage_id、外部キーとしてのようなものがある場合、それを取得するには、次のようなことを行う必要があります。CarRepository.getAll(new Criteria(carOwner.id, language.id));これにより、特定の言語の言語のすべての車が得られ​​ます-これが正しい方法です?
2015

@ StefanFalk、Spring Dataを見てください。それよりもはるかに優れた呼び出しを行うことができます。たとえば、次のように書くことができCarRepository.findByLanguageId(language.id)、コードを書く必要すらありません。その名前のメソッドでインターフェースを定義するだけで、Spring Dataがデフォルトのクラス実装を構築します。かなりすっきりしたもの;)
Stef

2
Spring Dataの優れている点は、実際にクエリを記述する必要がないことです。インターフェースを作成するだけです(例では、メソッドを含むTodoRepository findById)。そして、あなたは実際に終わりました。Spring Dataが行うことは、Repositoryインターフェースを拡張し、クラスを作成する、作成したこれらのインターフェースをすべて検出することです。これらのクラスが表示されることはなく、新しいインスタンスを作成することもできませんが、インターフェースを自動配線してSpringにそのリポジトリオブジェクトを見つけさせるだけでよいので、その必要はありません。
Stef、2015

1
最後に、Spring Dataを使用する必要はありません。(Criteria APIなどを使用して)クエリメソッドを自分で作成する古い方法を使用できますが、人生をもう少し複雑にするだけです...そのような柔軟性はありますが、クエリに夢中になりたい場合、Spring Dataでは2つの方法で@Queryアノテーションを使用できます。それが機能しない場合は、独自の実装を最初から作成する場合と同じ機能を提供する拡張機能であるカスタムリポジトリを作成します。
Stef、2015

2
「集約ルート」は、リポジトリパターンに関連することが多い用語です。リポジトリの定義でそれをどのように使用するかわかりません。
クリスチャンストレンファー

90

DAOとリポジトリパターンは、データアクセス層(DAL)を実装する方法です。それでは、まずDALから始めましょう。

データベースにアクセスするオブジェクト指向アプリケーションには、データベースアクセスを処理するためのロジックが必要です。コードをクリーンでモジュール化しておくために、データベースアクセスロジックを別のモジュールに分離することをお勧めします。階層化アーキテクチャでは、このモジュールはDALです。

これまでのところ、特定の実装については触れていません。データベースアクセスロジックを別のモジュールに配置するという一般的な原則のみです。

では、この原則をどのように実装できますか?特に、Hibernateのようなフレームワークでこれを実装する既知の方法の1つは、DAOパターンです。

DAOパターンはDALを生成する方法であり、通常、各ドメインエンティティには独自のDAOがあります。たとえば、Userand UserDaoAppointmentand AppointmentDao、など。Hibernateを使用したDAOの例:http : //gochev.blogspot.ca/2009/08/hibernate-generic-dao.html

次に、リポジトリパターンとは何ですか?DAOと同様に、リポジトリパターンもDALを実現する方法です。リポジトリパターンの主なポイントは、クライアント/ユーザーの観点からは、コレクションとして表示または動作する必要があるということです。コレクションのように動作するということは、のようにインスタンス化する必要があるということではありませんCollection collection = new SomeCollection()。代わりに、追加、削除、包含などの操作をサポートする必要があることを意味します。これがリポジトリパターンの本質です。

実際には、たとえばHibernateを使用する場合、リポジトリパターンはDAOで実現されます。つまり、DALのインスタンスは、DAOパターンとリポジトリパターンの両方のインスタンスに同時に存在できます。

リポジトリパターンは、必ずしもDAOの上に構築されるものではありません(一部の人が示唆するように)。DAOが上記の操作をサポートするインターフェースで設計されている場合、DAOはリポジトリパターンのインスタンスです。考えてみてください。DAOがコレクションのような一連の操作を既に提供している場合、その上に追加のレイヤーが必要なのは何ですか。


5
「DAOがコレクションのような一連の操作を既に提供している場合、その上に追加のレイヤーが必要なのは何ですか?」ペットショップをモデリングしていて、さまざまな動物とその属性(名前: "Cat"、タイプ: "Mammal"など)のテーブル 'PetType'があり、コンクリートペットのテーブル 'Pet'によって参照されているとします。ショップにいる(名前:「カトニス」、品種:「カリコ」など)。まだデータベースにないタイプの動物を追加する場合は、リポジトリを使用して2つの別々のDAO呼び出し(1つはPetTypeを作成し、もう1つはPetを作成する)を1つのメソッドにグループ化して、DAOでの結合を回避できます
Matt

1
すばらしい説明、サー!
Paul-Sebastian Manole

74

率直に言って、これは技術的な違いではなく、意味的な違いのように見えます。データアクセスオブジェクトというフレーズは、「データベース」をまったく指していません。また、データベース中心になるように設計することもできますが、ほとんどの人はそうすることを設計上の欠陥と考えるでしょう。

DAOの目的は、データアクセスメカニズムの実装の詳細を隠すことです。リポジトリパターンはどのように異なりますか?私の知る限りでは、そうではありません。オブジェクトのコレクションを処理したり返したりすることが正しくない場合があるため、リポジトリの記述はDAO とは異なります。DAOはオブジェクトのコレクションを返すこともできます。

私がリポジトリパターンについて読んだことはすべて、この区別に依存しているようです。悪いDAOデザインと良いDAOデザイン(別名リポジトリデザインパターン)。


5
うん、完全に同意します、それらは本質的に同じです。DAOはより多くのDB関連に聞こえますが、そうではありません。リポジトリと同じで、データの場所と方法を隠すために使用される単なる抽象化です。
Stef

+1このステートメントの場合。率直に言って、これは技術的な違いではなく、意味的な違いのように見えます。データアクセスオブジェクトというフレーズは、「データベース」をまったく指していません。
Sudhakar Chavali

1
リポジトリとコレクションを比較するときのポイントは、それらがオブジェクトのコレクションを処理または返すことではなく、リポジトリコレクション自体であるかのように動作することです。たとえば、Javaでは、コレクションのオブジェクトを変更すると自動的に更新されるため、リポジトリには更新メソッドがありません(Javaコレクションはオブジェクトへの参照のみを格納するため)。
クリストフBöhme

17

リポジトリは、ドメイン駆動設計の一部である、より抽象的なドメイン指向の用語であり、ドメイン設計の一部であり、共通言語です。DAOは、データアクセステクノロジーの技術的抽象概念です。データ。

これらのリンクを確認してください:

http://warren.mayocchi.com/2006/07/27/repository-or-dao/ http://fabiomaulo.blogspot.com/2009/09/repository-or-dao-repository.html


6

主な違いは、DAOがエンティティへのアクセスを処理するのに対して、リポジトリは集約内の集約ルートへのアクセスを処理することです。したがって、リポジトリが集約ルートの実際の永続性をDAOに委任するのが一般的です。さらに、集約ルートは他のエンティティのアクセスを処理する必要があるため、このアクセスを他のDAOに委任する必要がある場合があります。


5

DAOは、データベース/データファイルまたはその他の永続化メカニズムの抽象化を提供するため、永続化レイヤーは、その実装の詳細を知らなくても操作できます。

一方、Repositoryクラスでは、単一のRepositoryメソッド内で複数のDAOクラスを使用して、「アプリの観点」から操作を実行できます。したがって、ドメイン層で複数のDAOを使用する代わりに、リポジトリを使用してそれを実行します。リポジトリは、次のようないくつかのアプリケーションロジックを含む可能性のあるレイヤーです。データがメモリ内キャッシュで利用できる場合は、キャッシュからフェッチし、そうでない場合は、ネットワークからデータをフェッチして、次回の取得のためにメモリ内キャッシュに格納します。


3

リポジトリは、適切に設計されたDAOにすぎません。

ORMはテーブル中心ですが、DAOではありません。

車がどこにどのように永続化されていても、DAO自体がORMリポジトリ/エンティティまたは任意のDALプロバイダーとまったく同じように実行できるため、リポジトリで複数のDAOを使用する必要はありません。1テーブル、2テーブル、nテーブル、テーブルの半分、 Webサービス、テーブル、Webサービスなど。サービスは複数のDAO /リポジトリを使用します。

私自身のDAOは、CarDaoがCar DTOのみを処理するとします。つまり、入力でCar DTOのみを受け取り、出力でCar DTOまたはCar DTOコレクションのみを返します。

したがって、リポジトリと同様に、DAOは実際にはビジネスロジックのIoCであり、永続性インターフェイスを永続性戦略や遺産に脅かされないようにすることができます。DAOは永続性戦略をカプセル化し、ドメイン関連の永続性インターフェイスを提供します。リポジトリは、明確に定義されたDAOの実際が何であるかを理解していなかった人々のための単なる別の言葉です。


まず、「ORMリポジトリ/エンティティ」?ORMエンティティを意味します。ORMのリポジトリのようなものはありません。第二に、通常、ORMはエンティティのみを扱います。ドメインモデル。DAOはテーブルを直接処理し、データアクセスを抽象化します。エンティティも返します。リポジトリは最高の抽象概念であり、エンティティを取得するためのコレクションインターフェイスを提供します。DAOはレポジトリにすることができます。実際のストレージエンジンを抽象化し、それにインターフェースを提供し、(キャッシュ)エンティティのコレクションビューも提供します。DAOはORMを使用してデータベースとやり取りし、エンティティオペレーションを委任できます。
ポールセバスチャンマノール

3
@brokenthornに同意してください。彼のコメントで最も重要な点は「リポジトリは最高の抽象化である」であり、この抽象化は、基盤となるデータベーステクノロジーからドメインコードを保護したい場合に必要になります。ORM /アダプター/ DBドライバーの概念は、DAOにリークする傾向があります。複数のデータベーステクノロジーをサポートするアプリケーションがある場合、またはアプリをデータベースにロックしない場合は、ドメインモデルから直接DAOを使用することはできません。
Subhash Bhushan

2

DAOまたはリポジトリパターンが次の状況に最も当てはまるかどうかを確認してください。RDBMS、LDAP、OODB、XMLリポジトリなどのさまざまなタイプのデータソースに永続的なメカニズムのための統一データアクセスAPIを提供したいとします。フラットファイル。

興味がある場合は、次のリンクも参照してください。

http://www.codeinsanity.com/2008/08/repository-pattern.html

http://blog.fedecarg.com/2009/03/15/domain-driven-design-the-repository/

http://devlicio.us/blogs/casey/archive/2009/02/20/ddd-the-repository-pattern.aspx

http://en.wikipedia.org/wiki/Domain-driven_design

http://msdn.microsoft.com/en-us/magazine/dd419654.aspx


0

非常に単純な文で:大きな違いは、リポジトリがコレクションを表すのに対し、DAOはデータベースに近く、多くの場合、テーブル中心になっています。


DAOはコレクション/オブジェクトを表すこともできます...
Yousha Aleayoub

0

春のフレームワークには、リポジトリと呼ばれる注釈があり、この注釈の説明には、リポジトリに関する有用な情報が含まれています。これは、この議論に役立つと思います。

注釈付きのクラスが「リポジトリ」であることを示します。これは、もともとドメイン駆動設計(Evans、2003)によって「オブジェクトのコレクションをエミュレートするストレージ、検索、および検索動作をカプセル化するメカニズム」として定義されています。

「データアクセスオブジェクト」などの従来のJava EEパターンを実装するチームも、このステレオタイプをDAOクラスに適用できます。ただし、データアクセスオブジェクトとDDDスタイルのリポジトリの違いを理解してから行う必要があります。この注釈は汎用のステレオタイプであり、個々のチームはセマンティクスを絞り込み、必要に応じて使用できます。

このようにアノテーションが付けられたクラスは、PersistenceExceptionTranslationPostProcessorと組み合わせて使用​​した場合、Spring DataAccessException変換の対象になります。注釈付きクラスは、ツールやアスペクトなどの目的で、アプリケーションアーキテクチャ全体におけるその役割についても明確化されています。

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