web-dev-qa-db-ja.com

データマッパーとリポジトリの違いは正確には何ですか?

さて、私はデータマッパーとリポジトリの違いを見つけようとしてきましたが、今まで私はまだしていません。エキスパートプログラマーは、「リポジトリーは、クエリ構築コードが集中しているマッピングレイヤーの抽象化レイヤーの1つです」と言ったようです。それは理解できるように見えますが、それでもやや非常に抽象的なものです。以前にstackoverflowに関するこの記事を読みましたが、さらに混乱しました: データマッパーパターンはリポジトリパターンとどのように異なりますか?

私が必要としているのは、2つのパターンがどのように異なるか、リポジトリがデータマッパーが実行しないことを実行すること、およびその逆についての簡単な説明と具体的/実用的な例です。データマッパーとリポジトリの概念を説明する良い例を知っている人はいますか?同じ例で、1つはデータマッパーを使用し、もう1つはリポジトリを使用する方がよいでしょう。ありがとう、私はこれを非常に感謝します。私は今のところまだ非常に混乱しています...

21
Lord Yggdrasill

アプリケーションがPersonオブジェクトを管理し、各インスタンスがnameage、およびjobTitleプロパティを持っているとします。

そのようなオブジェクトを永続化し、永続化メディアから取得し、更新(たとえば、誕生日に、年齢をインクリメントする)または削除する必要があります。これらのタスクは通常、作成、読み取り、更新、削除からCRUDと呼ばれます。

「ビジネス」ロジックを、Personオブジェクトの永続性を処理するロジックから切り離すことが望ましいです。これにより、ビジネスロジックに影響を与えることなく、永続ロジックを変更できます(たとえば、DBから分散ファイルシステムに移行します)。

これを行うには、Repositoryの背後にあるすべての永続化ロジックをカプセル化します。架空のPersonRepository(または_Repository<Person>_)を使用すると、次のようなコードを記述できます。

Person johnDoe = personRepository.get(p=> p.name == "John Doe"); johnDoe.jobTitle = "IT Specialist"; personRepository.update(johnDoe);

これは単なるビジネスロジックであり、オブジェクトが保存される方法と場所は関係ありません。

Repositoryの反対側では、DataMapperと、クエリを機能記述から変換するもの(_p=> p.name == "John Doe"_を永続層が理解できるもの)の両方を使用します。

永続層はDBにすることができます。その場合、DataMapperPersonオブジェクトをPersonsTableの行との間で変換します。次に、クエリトランスレータは機能クエリを_SELECT * FROM PersonsTable WHERE name == "John Doe"_に変換します。

別の永続層は、ファイルシステム、またはPersonオブジェクトを2つのテーブルPersonAgePersonJobTitleに格納することを選択する別のDB形式にすることができます。

後者の場合、DataMapperは、johnDoeオブジェクトを2つの行に変換するタスクを実行します。1つはPersonAgeテーブル用で、もう1つはPersonJobTitleテーブル用です。次に、クエリロジックは、機能クエリを2つのテーブルのjoinに変換する必要があります。最後に、DataMapperは、クエリの結果からPersonオブジェクトを作成する方法を知っている必要があります。

大規模で複雑なシステムでは、独立して開発およびテストできる、明確に定義された小さなことを実行する小さなコンポーネントを使用する必要があります。

  • ビジネスロジックは、オブジェクトの読み取りまたは永続化を行うときにRepositoryを処理し、それがどのように行われるかは関係ありません実装済み
  • Repositoryは、特定の永続メディアでオブジェクトの読み取り/書き込みを行う場合にDataMapperを処理します。
  • クエリの場合、RepositoryDataMapperによって提供されるスキーマに依存します(たとえば、jobTitle値はJobTitleテーブルのPersonTable列にあります)が、マッパーの実装には依存しません。
  • DBの永続性については、DataMapperDBレイヤーに依存しており、Oracle/Sybase/MSSQL/OtherProviderの詳細からデータベースを保護します。

パターンは「異なる」のではなく、異なる基本的な機能を公開するだけです。

27
Andrei

この回答は少し遅いと思いますが、将来、同じ質問に出くわし、利用可能な回答が質問に完全に回答していないことに気付く人を助けるかもしれません(私がこの質問に最初に出会ったときに感じました) )。

PoEAA(Martin Fowler)を読んだ後、私もデータマッパーとリポジトリの違いを特定するのに苦労していました。

これは、2つの概念が最終的に次のようになることを私が見つけたものです。

  • a Repositoryドメインオブジェクトのコレクションのように機能し、強力なクエリ機能(Evans、DDD)を備えています
  • a DataMapper "オブジェクトとデータベースの間でデータを移動し、それらを互いに独立させ、マッパー自体から独立させます"(Fowler、PoEAA)

リポジトリは一般的な概念であり、必ずしもデータベースに何かを格納する必要はありません。その主な機能は、ドメインオブジェクトへの(クエリ対応の)アクセスのようなコレクションを提供することです(データベースから取得したかどうかは関係ありません)。ポイントの外にあります)。リポジトリには、DataMappers自体が含まれる場合があります(多くの場合、含まれます)。

DataMappersドメインオブジェクトとデータベースの間の中間層として機能し、一方が他方に依存することなく、それらを独立して進化させることができます。データマッパーには「検索」またはクエリ機能がある場合がありますが、それは実際には主な機能ではありません。 DataMappersで複雑なクエリロジックを使用していることがわかったほど、DataMappersをメイン機能として使用し、ドメインオブジェクトをデータベースにマッピングしたり、その逆を行ったりしながら、クエリロジックをリポジトリに分離することを検討し始めます。

21
shafeen