blog.fukuchiharuki

知ってる?リポジトリとDAOの違い

Posted at: March 28, 2017

リポジトリとDAO、どちらもデータベースなどのデータソースにアクセスするための設計パターンです。しかし、データベースにアクセスする、では括りが大き過ぎますね。

今回はリポジトリとDAOの違いについて書きます。クラスの役割を明確にした設計ができるように、違いをきちんと考えてみたいと思います。

仕組みを意識せずにデータアクセスできる、それがDAO

separates a data resource’s client interface from its data access mechanisms
Design Patterns: Data Access Object

データリソースを扱う窓口をデータアクセスのメカニズムから分離するのがDAOです。SQLなどを使ったデータアクセスを業務ロジックから切り離そうということですね。

DAO

DAOの関心はメカニズムをどうするかということにあります。データソースがデータベースであってもファイルであっても、利用する側はメカニズムを意識せずにデータアクセスできる、というものです。

では、リポジトリとは何でしょうか?

まるでドメインオブジェクトの集合、それがリポジトリ

A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.
P of EAA: Repository

ドメインとデータマッピングレイヤーを仲介し、in-memoryなドメインオブジェクトの集合のように振る舞うのがリポジトリです。

リポジトリ

“のように振る舞う”というのは、実際のところはどうであっても、ということです。つまり、インタフェースとしてはそうであるということですね。その実装がデータマッピングレイヤーをつなぐことになります。

それで、リポジトリとDAOはどう位置づけたらよいのでしょうか?

リポジトリはドメインオブジェクトを、DAOはデータアクセスを

An aggregate is a cluster of domain objects that can be treated as a single unit.
DDD_Aggregate

ドメインオブジェクトはaggregate(集約)という単位で取り扱うことができます。引用の参照元によるとaggregateは次の性質をもちます。

リポジトリは集約を対象にしてドメインオブジェクトを取り扱うようにするのがよさそうです。ここで、ドメインオブジェクトはデータベースのモデルと同じではありません。リポジトリの役割ははインピーダンス・ミスマッチを解消してドメインオブジェクトを提供することであると考えられます。

リポジトリとDAO

リポジトリのクライアントから見れば、データアクセスのメカニズムはリポジトに隠蔽されています。その意味でリポジトリはDAOであると考えることができます。しかし、実際のところO/RマッパーやSQLマッパーで直接ドメインオブジェクトを形成することはできないことが多いはずです。DAOの役割はリポジトリの代わりにデータアクセスすることであると考えれば役割の整理がつきそうです。

まとめ

Martin Fowlerさんの解説を引用してリポジトリとDAOの違いについて考えてみました。リポジトリとDAOは関心の対象が異なり、違う役割・レイヤに位置づけることができると解釈しました。

この解釈に従って、実際にSpring MVCとMyBatisを使ったWebアプリケーションを開発してみています。POJOで構成するドメインオブジェクトとMyBatisに依存する実装を切り分けることができて、すっきりしたように思います。この実装の詳細はまた別の記事で。