Data Access Object — データソース(DB・ファイル・API)への CRUD 操作を 1 箇所に集約し、上位層からデータアクセスの実装詳細を隠す設計パターン。Sun Microsystems の J2EE Core Patterns(1999)で広く知られた。
概要
DAO は 「データソースの種類が変わってもビジネスロジックを書き換えなくて済む」 ようにするのが目的。SQL・JDBC・JPA・ファイル I/O などの低レベル詳細を DAO に閉じ込め、上位層には findById(id) のようなメソッド呼び出しだけを公開する。
ビジネス層
└─ UserDao.findById(123)
│
▼
DAO 実装(JdbcUserDao)
└─ SELECT * FROM users WHERE id = 123
典型 API
| 操作 | メソッド例 |
|---|---|
| 取得(単一) | findById(id) |
| 取得(複数) | findAll() / findByCondition(...) |
| 作成 | insert(record) |
| 更新 | update(record) |
| 削除 | delete(id) |
戻り値は DTO・レコード型 が中心。集約・値オブジェクトを直接返すことは少ない。
リポジトリパターンとの違い
DAO とリポジトリパターンはよく混同されるが、設計上の意図が異なる。
| 観点 | DAO | リポジトリ |
|---|---|---|
| 抽象レベル | テーブル / SQL に近い | ドメイン語彙(集約) |
| 配置層 | データアクセス層 | インターフェースはドメイン層 |
| 戻り値 | DTO / レコード | 集約・値オブジェクト |
| メソッド粒度 | テーブル単位の CRUD | 業務語彙(findActiveCustomers) |
| 主目的 | データアクセスの再利用 | ドメインの純度を保つ |
| 由来 | J2EE Core Patterns | DDD(Eric Evans) |
DDD を採用するならリポジトリ、CRUD 主体のアプリなら DAO という使い分けが現実的。
DAO が向く場面
- データソースが頻繁に変わる可能性がある(DB 移行、API 切り替え)
- ドメインモデルが薄く、DB スキーマがほぼそのまま業務オブジェクトになる CRUD アプリ
- 既存のレガシーコードに段階的に永続化抽象を導入したい
DAO が過剰な場面
- 集約と業務ルールが厚い領域(リポジトリの方が適切)
- 1 ファイルで完結する小規模スクリプト
レガシーシステムでの DAO
COBOL でも DAO 的な責務分離は実現できる。ビジネスロジックを記述するプログラムから embedded SQL を直接書かず、データアクセス専用のサブプログラムに切り出す構造がそれにあたる。モダナイゼーション時には、この単位がそのまま DAO もしくはリポジトリ実装の境界候補になる。
関連記事
- 開発手法ガイド:概要 — DDD 系列での位置づけ
- COBOL × DDD 設計パターン — レガシーへのデータアクセス分離適用例
関連用語
- リポジトリパターン — DDD 文脈での DAO の発展形
- SoC(関心の分離) — DAO が体現する分離原則
- SOLID 原則 — DAO は SRP の典型適用
- embedded SQL — DAO で隠蔽する低レベル詳細の代表