リポジトリとDAOの違いは目的の違いで捉える
リポジトリとDAOの違いは何で、どう捉えられるか。参考文献を引用しながらそれぞれの目的を整理し、リポジトリとDAOをどう使い分けられそうかを考えてみます。
リポジトリはドメインオブジェクトのコレクション
リポジトリはエンタープライズアプリケーションアーキテクチャパターンやドメイン駆動設計で提唱されている設計パターンです。
A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.
-- P of EAA: Repository
リポジトリはエンタープライズアプリケーションアーキテクチャパターンにおいて次のように説明されています。リポジトリはドメインとデータマッピングレイヤをとりなして、インメモリなドメインオブジェクトのコレクションのように振る舞います。
Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, [...]
-- P of EAA: Repository
リポジトリはドメインオブジェクトの永続化に関わる操作を隠蔽しているとも言えます。
[...]それ自体はドメインに由来しないが、ドメイン設計においては意味のある役割を持っている。これらの構成概念は、モデルオブジェクトを操作できるようにすることで、[...]
-- エリック・エヴァンスのドメイン駆動設計
また、エリック・エヴァンスのドメイン駆動設計において次のように説明されています。リポジトリの目的はドメインオブジェクトを操作できるようにすることです。リポジトリそのものはモデルではないとのことです。
DAOはデータアクセスのメカニズムを隠蔽する
DAOはエンタープライズアプリケーションの標準的なアーキテクチャとしてJava EE (J2EE)を通して普及が推進されてきた設計パターンです。
separates a data resource's client interface from its data access mechanisms
-- Design Patterns: Data Access Object
DAOはデザインパターンのひとつです。DAOはデータリソースのクライアントインタフェースをデータアクセスのメカニズムから分離します。データアクセスのメカニズムを隠蔽する点はリポジトリと同じです。
The DAO pattern allows data access mechanisms to change independently of the code that uses the data.
-- Design Patterns: Data Access Object
DAOの目的はデータを利用するコードから独立してデータアクスのメカニズムを変更できるようにすることです。
リポジトリとDAOは関心の向きに違いがある
リポジトリとDAOにはそれぞれ違った目的があります。リポジトリの目的はアプリケーションコードにてドメインオブジェクトを操作できるようにすることです。DAOの目的はアプリケーションコードから独立してデータアクセスのメカニズムを変更できるようにすることです。
ここで、リポジトリとDAOはアプリケーションコードとデータストアの間に位置する点で一致しますが、関心の向きに違いがあると言えそうです。リポジトリの関心はドメインオブジェクトにあり、DAOの関心はデータアクセスのメカニズムにあります。
リポジトリとDAOを使い分ける
リポジトリとDAOをどう使い分けられるかを考えてみます。
まず、DAOの実装としてJPAやMyBatisなどのライブラリがあります。DAOはデータアクセスのメカニズムを隠蔽します。JPAやMyBatisを利用すれば、インタフェースを用意するだけでアプリケーションコードにてデータベースのエンティティを取得・操作できます。JPAやMyBatisがその実装を引き受けてこれを隠蔽してくれています。
次に、リポジトリの実装としてドメインオブジェクトを構築するサービスを考えます。リポジトリは「ドメインオブジェクトのコレクション」としての振る舞います。ドメインオブジェクトはデータベースのエンティティから組み立てますが、ドメインオブジェクトの構成はデータベースのエンティティの構成と同じではないので、データベースのエンティティからドメインオブジェクトを構築するマッピングのメカニズムが必要です。リポジトリがその役割を担います。
これを図にしてみます。
なお、JPAではドメインオブジェクトの構成とデータベースのエンティティの構成を柔軟にマッピングできます。JPAを適切に利用すれば、リポジトリの役割りとDAOの役割りを兼ねてデータアクセスを実装できます。
まとめ
リポジトリとDAOの違いは目的の違いに着目して捉えるのがよさそうです。
リポジトリの目的はアプリケーションコードにてドメインオブジェクトを操作できるようにすることです。リポジトリはデータベースのエンティティからドメインオブジェクトを構築することで、ドメインオブジェクトのコレクションのように振る舞います。
DAOの目的はアプリケーションコードから独立してデータアクセスのメカニズムを変更できるようにすることです。DAOはクライアントインタフェースを設けることで、データアクセスのメカニズムを隠蔽します。
リポジトリとDAOの使い分け方はアプリケーションコードに対する役割と隠蔽するメカニズムで整理できます。
Discussion