CTS-KB

DAO

でぃーえーおー

Data Access Object データアクセスオブジェクト
#設計パターン #データアクセス #永続化

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 PatternsDDD(Eric Evans)

DDD を採用するならリポジトリ、CRUD 主体のアプリなら DAO という使い分けが現実的。

DAO が向く場面

  • データソースが頻繁に変わる可能性がある(DB 移行、API 切り替え)
  • ドメインモデルが薄く、DB スキーマがほぼそのまま業務オブジェクトになる CRUD アプリ
  • 既存のレガシーコードに段階的に永続化抽象を導入したい

DAO が過剰な場面

  • 集約と業務ルールが厚い領域(リポジトリの方が適切)
  • 1 ファイルで完結する小規模スクリプト

レガシーシステムでの DAO

COBOL でも DAO 的な責務分離は実現できる。ビジネスロジックを記述するプログラムから embedded SQL を直接書かず、データアクセス専用のサブプログラムに切り出す構造がそれにあたる。モダナイゼーション時には、この単位がそのまま DAO もしくはリポジトリ実装の境界候補になる。

関連記事

関連用語